I have created an Arduino Library for a device, of which it can be generally configured in several ways. E.g. use interrupts or poll it. From other examples I have created the following files: foo.h, fooConfig.h and foo.cpp shown below for the library. Where fooConfig.h contains the configuration of how to use the shield. Such as with or without interrupts etc...
In doing so I would like the main sketch's INO file to be able to over-ride default settings, which have been declared using #define's. Including in the library's instance. The results show it really does. At least the way I am doing it.
The below code is a simplified example with the problem:
definetest.ino
#define BAR USE_POLL
#include <foo.h>
foo test;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.print(F("setup's defined BAR was "));
Serial.println(BAR);
Serial.print(F("inside foo.begin defined BAR was "));
Serial.println(test.begin());
}
void loop() {
}
foo.h
#ifndef FOO_h
#define FOO_h
#include "FOOConfig.h"
class foo {
public:
int begin();
};
#endif // FOO_h
FooConfig.h
#ifndef FOOCONFIG_h
#define FOOCONFIG_h
#define USE_INT 1
#define USE_POLL 2
#ifndef BAR
//default to using interrupts
#define BAR USE_INT
#endif // BAR
#endif // FOOCONFIG_h
foo.cpp
#include <foo.h>
int foo::begin() {
#if defined(BAR) && BAR == USE_INT
Timer1.attachInterrupt( isr ); // error here, because of the define...
return 1;
#elif defined(BAR) && BAR == USE_POLL
return 2;
#endif
return 0;
}
Yields the following serial output:
setup's defined BAR was 2
inside foo.begin defined BAR was 1
Where it was desired to have the BAR inside the foo.begin equal to 2, not 1. Noting it is desired to have the precompiler decide to or not omit the attachInterrupt. Don't want the dependancy and consumption of the resources of the library if it is not used. Simply want it to be an advanced option.
I understand this may best handled with a make file or eclipse, but I am trying to publish this library for the Arduino IDE currently at 1.0.3.
Any help is appreciated.
FYI, the real and whole code is here. https://github.com/mpflaga/Sparkfun-MP3-Player-Shield-Arduino-Library/tree/master/SFEMP3Shield
Regardless of tool chain, the program does not and should not determine how the library is compiled. A key concept of a library is that it is fully developed, compiled and packaged without the existence of any program. There is a one way dependency: a program depends on the library -- a library has no dependency on any program. A key point that highlights this is that you do not have to distribute source code to use a library. A library can be used with just headers and binary (.a) Take a peek into all the WinAvr libraries that are used.
What you are seeking is how to have multiple configurations of your library. In other tool chains this is readily done at the project level where you can create any number of output configurations. In your case you would have poll and int, and the toolchain would produce two libraries, for example:
libMySomething_int.a
libMySomething_poll.a
Programs choose which configuration of the library they wanted to use.
As noted by others, the Arduino IDE will not provide for this form of complexity. Since you stated you intend to stay within that toolchain, these are solutions I can see:
Make two copies of the library that differ just by the one #define. This is basically you providing the two configurations. Because they differ by a tiny amount, it will be easy to WinMerge between to two and keep codebases synchronized.
Rethink whether it is necessary to have one interface to the two forms. You do not have to have just one begin(), you can have two forms:
void beginInt();
void beginPoll();
void getSomethingInt();
void getSomethingPoll();
Keep in mind that this does not waste code space. The linker will remove all unused functions from the final program, so if you just use the Int form, all the Poll functions get dropped.
The choice between these two isn't clear and somewhat subjective. The decision should consider what you are intended to encapsulate/hide in the library, and what you want to make clear. If this library was an interface to a variety of real time clock chips, then you would clearly be fair to encapsulate all the differences and provide one set of functions. But in your case you are implying key changes in resource consumption, timing, and concurrency -- I'm not sure it is best to hide this.
The Arduino IDE compiles libraries individually so you would need to pass the define as a -D option during the compile. The Arduino IDE does not currently provide a facility for you to easily do that. Arduino 1.5 provides some functionality via the boards.txt system but this probably will not provide the flexibility you need.
So, as you say, the options are editing make files in products such as Eclipse or by setting one of the "Defines" project properties (such as "Defines - Project") in Visual Studio Pro.
Or by using the TeensyDuino IDE and adding your own menu.
defs to the boards.txt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With