Go Down

Topic: Problem with conditional #include (Read 2877 times) previous topic - next topic

Jack Christensen

I have two interchangeable libraries that implicitly define the same object (RTC) and are therefore mutually exclusive. I want to include one or the other, based on a #defined value. The code below seems to act as though both libraries are being included. If I explicitly comment one library or the other out with "//" then I can get it to compile.

This seems simple, I must be missing something fundamental.

Code: [Select]
#define RTC_TYPE 1

#include <Time.h>           //http://www.arduino.cc/playground/Code/Time
#include <Wire.h>           //http://arduino.cc/en/Reference/Wire

#if RTC_TYPE == 1
#include <DS1307RTC.h>      //http://www.arduino.cc/playground/Code/Time
#else
#include <MCP79412RTC.h>    //https://github.com/JChristensen/MCP79412RTC
#endif

void setup(void)
{
    setSyncProvider(RTC.get);
}

void loop(void)
{
}

Compiler output:

MCP79412RTC\MCP79412RTC.cpp.o:C:\Documents and Settings\Jack\My Documents\arduino\sketchbook\libraries\MCP79412RTC/MCP79412RTC.cpp:551: multiple definition of `RTC'
DS1307RTC\DS1307RTC.cpp.o:C:\Documents and Settings\Jack\My Documents\arduino\sketchbook\libraries\DS1307RTC/DS1307RTC.cpp:112: first defined here

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

patduino

At a quick glance it looks ok. Unless one library includes the other in error (doubt it).

Try this to see what the preprocessing is doing.  Change the #define to see what happens...  (I would, but I'm not near my compiler)

Code: [Select]

#if RTC_TYPE == 1
#include <DS1307RTC.h>      //http://www.arduino.cc/playground/Code/Time
#error DS1307RTC
#else
#include <MCP79412RTC.h>    //https://github.com/JChristensen/MCP79412RTC
#error DS1307RTC
#endif
There are 10 types of people in the world, those that understand binary, and those that don't.

Jack Christensen

@patduino, I get one #error or the other, not both. Double-checked my library just to verify that it doesn't include the other, and it doesn't.


At a quick glance it looks ok. Unless one library includes the other in error (doubt it).

Try this to see what the preprocessing is doing.  Change the #define to see what happens...  (I would, but I'm not near my compiler)

Code: [Select]

#if RTC_TYPE == 1
#include <DS1307RTC.h>      //http://www.arduino.cc/playground/Code/Time
#error DS1307RTC
#else
#include <MCP79412RTC.h>    //https://github.com/JChristensen/MCP79412RTC
#error MCP79412RTC
#endif

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Coding Badly


Jack Christensen

I was thinking compiler...

Code: [Select]
MCP79412RTC\MCP79412RTC.cpp.o:C:\Documents and Settings\Jack\My Documents\arduino\sketchbook\libraries\MCP79412RTC/MCP79412RTC.cpp:551: multiple definition of `RTC'
DS1307RTC\DS1307RTC.cpp.o:C:\Documents and Settings\Jack\My Documents\arduino\sketchbook\libraries\DS1307RTC/DS1307RTC.cpp:112: first defined here




Linker error?
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

patduino

Quote
I get one #error or the other, not both.


That implies that the preprocessor is handling the conditionals correctly.  Hmmmmm.

Do you have code somewhere else, like in another tab, that might be compiling too?
There are 10 types of people in the world, those that understand binary, and those that don't.

Jack Christensen


Quote
I get one #error or the other, not both.


That implies that the preprocessor is handling the conditionals correctly.  Hmmmmm.

Do you have code somewhere else, like in another tab, that might be compiling too?


Nope, the code I posted is everything, single tab. The problem originally occurred in a larger project with multiple tabs, but I like to pare things down to the minimum that still exhibits the issue. Better for the forum I figure too.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Jack Christensen

More info:

1. Checked the build folder, it contains sub-folders for both libraries with object files.

2. Tried it on another PC (new build) ... same results.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Jack Christensen

Verbose compiler output attached.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

el_supremo

This looks like the infamous IDE trick of blowing #ifdef away.
Try putting
Code: [Select]
char junk; at the front of the file.

Pete

Jack Christensen


This looks like the infamous IDE trick of blowing #ifdef away.
Try putting
Code: [Select]
char junk; at the front of the file.

Pete


The library (.h) file?
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

el_supremo

In your .ino file - it should work as long as it is in front of
Code: [Select]
#if RTC_TYPE == 1

Pete

Jack Christensen


In your .ino file - it should work as long as it is in front of
Code: [Select]
#if RTC_TYPE == 1

Pete


Hmmm, no change:

Code: [Select]
char junk;
#define RTC_TYPE 1

#include <Time.h>           //http://www.arduino.cc/playground/Code/Time
#include <Wire.h>           //http://arduino.cc/en/Reference/Wire

#if RTC_TYPE == 1
#include <DS1307RTC.h>      //http://www.arduino.cc/playground/Code/Time
#else
#include <MCP79412RTC.h>    //https://github.com/JChristensen/MCP79412RTC
#endif

void setup(void)
{
    setSyncProvider(RTC.get);
}

void loop(void)
{
}


Code: [Select]
MCP79412RTC\MCP79412RTC.cpp.o:C:\Documents and Settings\Jack\My Documents\arduino\sketchbook\libraries\MCP79412RTC/MCP79412RTC.cpp:552: multiple definition of `RTC'
DS1307RTC\DS1307RTC.cpp.o:C:\Documents and Settings\Jack\My Documents\arduino\sketchbook\libraries\DS1307RTC/DS1307RTC.cpp:112: first defined here
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

pico

This is a well documented and well known failing of the Arduino IDE preprocessor. It doesn't respect (or simply ignores) the preprocessor conditionals, and will aggressively match any line starting with #include for a library inclusion.

It's been reported as a problem for years. Like many other problems with the IDE preprocessor, Team Arduino don't think it's a big deal, apparently, so it's not going to be fixed.

My solution is to simply not use the IDE to avoid the numerous bugs and problems in the IDE preprocessor altogether. I use makefiles that do the build. I need to declare my own prototypes, and put a list of user libraries I'm using in a makefile script for that project. Done. No IDE preprocessor. Real C/C++ preprocessor directives all work as expected again. Life is better that way.


WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

Jack Christensen


This is a well documented and well known failing of the Arduino IDE preprocessor. It doesn't respect (or simply ignores) the preprocessor conditionals, and will aggressively match any line starting with #include for a library inclusion.

It's been reported as a problem for years. Like many other problems with the IDE preprocessor, Team Arduino don't think it's a big deal, apparently, so it's not going to be fixed.


Understood, thanks. Guess I'd missed that one.

Quote

My solution is to simply not use the IDE to avoid the numerous bugs and problems in the IDE preprocessor altogether. I use makefiles that do the build. I need to declare my own prototypes, and put a list of user libraries I'm using in a makefile script for that project. Done. No IDE preprocessor. Real C/C++ preprocessor directives all work as expected again. Life is better that way.


I've read various threads on this approach, and made a couple half-hearted attempts but didn't stick to it long enough to get it working. I'd probably be happier working that way, too. Declaring prototypes is another thing I don't appreciate the IDE doing for me; it doesn't always get it right.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Go Up