-
-
Notifications
You must be signed in to change notification settings - Fork 7k
IDE doesn't honor preprocessor conditionals when including libraries #1841
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What happens here is that the Arduino IDE finds #include lines in the source and, based on those, includes libraries in the link. In your example, when actually compiling your sketch, Servo.h will not be included and no functions inside it will be called, but the Servo library will still be included in the link. AFAIU, any functions inside the Servo library that are not used should be removed from the final link (because of As for solving this - that might prove difficult. Naïvely, I would say to just run gcc in preprocessor-only mode ( We could again solve this by doing a two-step process: First apply the current naïve "find #include directives" filter, which results in a list of potentially included libraries. Add those to the include path and run An alternative would be to use To really make this work reliably (e.g., to allow the sketch to only |
This upsets me a lot. Unless I'm wrong, it makes conditional The example I am working with is Adafruit's motorshields:
Which results in
Not a C expert of course, but the docs I read about it seem to suggest this is a kosher preprocessor pattern. Accept that this is a hard problem to fix - but it can't be uncommon in exactly this kind of situation. |
Dear Sandy, This is a known behavior of the Arduino IDE. *Your_sketch.ino * .... conditionnal_includes.h #ifdef ADAFRUIT_MOTORSHIELD_V1 #ifdef ADAFRUIT_MOTORSHIELD_V2 This should work 2014-10-05 16:40 GMT+02:00 Sandy Noble [email protected]:
|
Thanks @barbudor that makes some sense - and indeed it does correctly prevent the includes from happening if neither case is true. I suppose it is obvious now that I need to be able to specify the exact path to the libraries in the conditional_includes.h because the IDE won't do it's auto-find magic on the I see the problem! Thanks for guide. |
The IDE does not honor conditional preprocessor conditionals when generating function prototypes either. For example:
This gives the error:
Also, the line number (4) is wrong. I understand why this is happening, but it is frustrating trying to explain to forum users who post stuff like "but it should be ignoring foo!". |
Much of these problems could be resolved with a |
Here is an example on how to pick out the needed includes from command line on Linux:
Certainly something this simple can be done. I could patch it myself with ease. I could even add the extra properties stuff too. As a shield driver developer I find it very frustrating to tell users that they need to modify headers in a library every time they switch to a project that has a different setup. Its ridiculous, considering these fixes are so easy to do. I really don't understand the reasoning behind rejecting modifications that would help everybody, especially someone who is new to everything, and they get all nervous when they have to edit something unrelated to their project, and/or forget to make changes and end up blaming the dev. |
Even better: |
Last time, really. this one is the best:
|
There is a fundamental problem here: What include paths do you pass to the preprocessor run to determine the libraries to include? What if some libraries are included conditionally based on defines in another library? There's probably just no perfect DWIM solution here, I'm afraid... |
I've posted a "solution" here: http://www.gammon.com.au/forum/?id=12625 Basically you leave the .ino file empty, or at the most, just put the #include statements in for any libraries that you need. That way, it effectively becomes a "project" file simply listing what libraries need to be copied to the compilation area. Then your main code goes into .cpp (or .c) files which you add to the project, and which are not subject to this pre-processor mangling. |
The errors from gcc -E tell you what headers to look for to include the libraries. |
So that you 'get the full idea'...
Understand now? |
My point is this... |
I understood your point, and I guess looking at gcc error messages is a decent way to detect library includes. As you say - no point to write another compiler, you'll only do it poorly. However, I made a more general point - I'll add a short example:
Scanning preprocessor output for missing includes shows only LibraryA, while it might also need LibraryB. |
That one is pretty simple. Here, some pseudo code.
|
and before you ask... the missing case...
|
I love sh so much... I just had to do it...
LOL |
The solution you propose crossed my mind and solves the one example I gave, but it does not solve all cases. In general, it seems to be hard to find a way to solve all corner cases. Here's another example (I'm not inviting you to solve it - I'm just trying to show you that this is a non-trivial, perhaps even unsolvable, problem):
When A defines |
The recursion would resolve it properly.
|
Hint... add one new path at a timem....
|
I guess you mean iteration, not recursion (looking at your C version, not the sh version)? In any case, your proposed code would not handle this case properly. If modified to only add one path per gcc run, it would, but I'm pretty sure that I can keep coming up with counter-examples for this - it's just a complex problem. One approach that might work, is to do the #include matching as now, so find all #include lines, ignoring any preprocessor directives. Then, add all of the detected libraries to the include path, run the preprocessor and ask which files were actually #included. Then, for the final compilation, only use those libraries. Tricky part here is how to run just the preprocessor - platform.txt doesn't currently have any lines for this... |
It will be tested in my makefile system in a few days. I'll let you know if
|
Please checkout this thread [1] on devs mailing list and try one of the linked IDEs. It should fix the problems reported in this issue |
A new version of the new preprocessor is available. Links available at the bottom of this email |
New preprocessor tracked at #2636. Builds for testing it are available |
Fixed by #3779 |
In the Arduino IDE 1.5.5, the default sketch on the Uno compiles to 466 bytes:
Including Servo.h, it compiles to 1104:
I would therefore expect the following code to compile to 466 bytes, but this is not the case:
However, commenting out the include statements does prevent the library from being included:
This caused some headache for me as I tried to figure out why my sketch size was so large despite not including any libraries. This is not the behavior I think anyone would expect from the IDE.
The text was updated successfully, but these errors were encountered: