Trying to write code that builds differently between Uno and Esplora

I'm writing a sketch with the following code that will automatically build in different ways for Uno vs Esplora:

#include <SPI.h>

#ifdef __AVR_ATmega32U4__   // This is true for Esplora but not for Uno
#include <Esplora.h>
#endif

void setup() { ... }

void loop() { ... }

The problem is that the Arduino IDE attempts to build Esplora.cpp based on the mere presence of the line "#include <Esplora.h>" even for Arduino Uno. The Arduino preprocessor ignores the C preprocessor it seems like. And the attempt to build fails because Esplora.cpp contains some names that aren't defined for Uno.

This seems to have been noted in the past, and not yet addressed:
http://code.google.com/p/arduino/issues/detail?id=906

Is there any alternative way I can write this code in a way that doesn't require manually editing it when switching between Uno and Esplora?

I'm writing a sketch with the following code that will automatically build in different ways for Uno vs Esplora:

That I'm sure doesn't look anything like that.

The Arduino preprocessor ignores the C preprocessor it seems like.

No, it doesn't. It modifies your ino file in converting it to a cpp file that the compiler can deal with. Doing that sometimes causes problems when conditional compilation instructions are present in the ino file.

The simplest solution is to make line 1 of your ino file:

byte heyStupidAddCodeAfterMe;

That way, the IDE will add it's stuff in the right place, rather than in the middle of your conditional compilation block.

PaulS:

I'm writing a sketch with the following code that will automatically build in different ways for Uno vs Esplora:

That I'm sure doesn't look anything like that.

You're partly right, I'm including one of my own custom libraries that only calls into Esplora library for Atmega32U4. For Uno, it implements alternative functionality. The "#include <Esplora.h>" in the main sketch is just to tell the IDE to build and link in the Esplora library.

The Arduino preprocessor ignores the C preprocessor it seems like.

No, it doesn't. It modifies your ino file in converting it to a cpp file that the compiler can deal with. Doing that sometimes causes problems when conditional compilation instructions are present in the ino file.

The simplest solution is to make line 1 of your ino file:

byte heyStupidAddCodeAfterMe;

That way, the IDE will add it's stuff in the right place, rather than in the middle of your conditional compilation block.

I tried that and it didn't help. Here is the compiler error I'm getting:
/Applications/Arduino.app/Contents/Resources/Java/libraries/Esplora/Esplora.cpp:54: error: 'A11' was not declared in this scope

The build error is not happening in my sketch. It's happening when it builds Esplora.cpp.

In fact, you can build this simple sketch yourself for Uno to see what I mean:

byte foo;

#ifdef __ATmega32U4__
#error "Should not build"
#include <Esplora.h>
#endif

void setup() { }
void loop() { }

The IDE is ignoring the #ifdef statement when it decides that the Esplora library needs to be compiled. If you enable verbose compilation, and look at the build directory, you'll see that the Esplora library is referenced, even though it won't be linked to. That the references are there, though, causes it to be compiled.

This works, though:

byte foo;

#include "stuff.h"

void setup() { }
void loop() { }

stuff.h:

#ifdef __ATmega32U4__
#error "Should not build"
#include <Esplora.h>
#endif

That works for Uno but breaks Esplora unfortunately. The Arduino IDE won't know to include the Esplora library because there is no longer an #include for it in the main sketch.

I think I will just have to add a copy of the Esplora library to my own library, and then wrap it in the #ifdef.

Further suggestions are welcome but I think that is the most straightforward way for now. Thanks for your help.

I have the same problem with Arduino/Teensy vs. ATtiny85 with the Wire library.

I've been planning to move my code to a library, using a basic class to hold all of the places where the 2 are different (using virtual functions for each call). I would rename the loop and setup functions in the library (presumably class functions) and then create two separate main sketches, one for the ATtiny85 and one for the Arduino/Teensy. Each would create a super class that inherits the base class, adding the appropriate virtual functions, and adding other includes, etc. That ways the TinyWireM.h header would only be included in the sketch for ATtiny85, and Wire.h would be include in the Arduino/Teensy sketch.

eecsninja:
That works for Uno but breaks Esplora unfortunately. The Arduino IDE won't know to include the Esplora library because there is no longer an #include for it in the main sketch.

I think I will just have to add a copy of the Esplora library to my own library, and then wrap it in the #ifdef.

Further suggestions are welcome but I think that is the most straightforward way for now. Thanks for your help.

I copied the stuff.h stuff, opened the IDE, creates a new tab called stuff.h, and pasted the stuff I copied. I then copied and pasted the sketch stuff in the sketch tab. I selected Arduino Esplora, and clicked Verify. I got one "error":

Binary sketch size: 4,242 bytes (of a 28,672 byte maximum)

I guess I don't understand how you are defining "works".

PaulS:

eecsninja:
That works for Uno but breaks Esplora unfortunately. The Arduino IDE won't know to include the Esplora library because there is no longer an #include for it in the main sketch.

I think I will just have to add a copy of the Esplora library to my own library, and then wrap it in the #ifdef.

Further suggestions are welcome but I think that is the most straightforward way for now. Thanks for your help.

I copied the stuff.h stuff, opened the IDE, creates a new tab called stuff.h, and pasted the stuff I copied. I then copied and pasted the sketch stuff in the sketch tab. I selected Arduino Esplora, and clicked Verify. I got one "error":

Binary sketch size: 4,242 bytes (of a 28,672 byte maximum)

I guess I don't understand how you are defining "works".

That's because you don't have another library that references things in the Esplora library. Here's my build error:

/Users/eecsninja/Documents/Arduino/libraries/DuinoCube/DuinoCube.cpp: In static member function 'static void DuinoCube::begin()':
/Users/eecsninja/Documents/Arduino/libraries/DuinoCube/DuinoCube.cpp:65: error: 'Esplora' was not declared in this scope
/Users/eecsninja/Documents/Arduino/libraries/DuinoCube/DuinoCube.cpp:65: error: 'SWITCH_1' was not declared in this scope
/Users/eecsninja/Documents/Arduino/libraries/DuinoCube/DuinoCube.cpp:66: error: 'SWITCH_2' was not declared in this scope
/Users/eecsninja/Documents/Arduino/libraries/DuinoCube/DuinoCube.cpp:67: error: 'SWITCH_3' was not declared in this scope
/Users/eecsninja/Documents/Arduino/libraries/DuinoCube/DuinoCube.cpp:68: error: 'SWITCH_4' was not declared in this scope

Because there is no "#include <Esplora.h> in the main sketch, the Arduino IDE doesn't know to provide Esplora.h to the other library, DuinoCube.