IDE include path bug

There is a serious issue with include paths when using .cpp files. It can be demonstrated as follows:

Create a new sketch using IDE version 1.0.5
Add a new file called “test.cpp”
Paste the following code into test.cpp:

#include <SPI.h>
void test(){SPI.begin();}

Attempt to compile. It fails as follows (verbose detail shown):

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -IC:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\variants\standard C:\Users\myuser\AppData\Local\Temp\build5595337925678702317.tmp\foo.cpp -o C:\Users\myuser\AppData\Local\Temp\build5595337925678702317.tmp\foo.cpp.o 
foo.cpp:1:17: warning: SPI.h: No such file or directory
foo.cpp: In function 'void test()':
foo.cpp:2: error: 'SPI' was not declared in this scope

The same code compiles fine when pasted into the main file instead of a separate .cpp file. The issue appears to be the generation of the include paths for the g++ command. When using a .cpp file, the include path for SPI.h is not added automatically. Nor can I find any options to manually add it. The result is that libraries can’t be used from a .cpp file.

When using a .cpp file, the include path for SPI.h is not added automatically. Nor can I find any options to manually add it.


#include <SPI.h>

…to top of the sketch (INO or PDE file).

Please note the 'Add' to .ino file. I read this post and 'moved' the #include from the .h to the .ino and it did not work. It was only by chance that I found out that it works if the #include is in the .ino and the .h (for whatever reason).

There is a serious issue with include paths when using .cpp files. It can be demonstrated as follows:

No, there isn't. The bug involves you not understanding the build process, having not read the section of the reference page dealing with the build process.

The sketch is converted to a cpp file, and it, and all files on other tabs, are copied to a build directory. Any file referenced IN THE SKETCH, is also copied, along with its source file, if relevant. Then, the compiler runs.

Since SPI.h was not referenced in the sketch, it was not copied SO IT IS NOT AVAILABLE to include in the other file.

The Arduino IDE pre-preprocessin reads the .ino file in order to build the search paths (for .h files) used during the compile of all the files in the project. So if a library .h file isn't mentioned in the .ino file, it's directory isn't in the search paths, and compiles of the .cpp files won't find it.
(Source code isn't actually copied, except for the sketch .ino files that are all written to a .cpp file in the build directory.
For example, here's the IDE compiling wire.cpp:

/Applications/arduino/ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106 -I/Applications/arduino/ -I/Applications/arduino/ [color=maroon]-I/Applications/arduino/[/color] -I/Applications/arduino/ [color=purple]/Applications/arduino/[/color] [color=teal]-o /var/folders/jz/5yb8f2hr8xjcpf0059bsfz4r0000gn/T/build7578358985282342496.tmp/Wire/Wire.cpp.o [/color]

Today I worked on this problem.

Help is needed for testing, especially with uncommon combinations of libraries, and on different systems (I've only tested on Linux... no testing yet on Mac or Windows).

If anyone is still watching this thread and cares about this issue, now's the time to download the PR-2792-BUILD-282 copy from that GitHub page. Give it a try and see if it solves this issue, or not? Please comment on the GitHub page (where the Arduino devs will see your words). Testing from multiple users is the next step needed for this to become officially part of Arduino.

The thing I don’t like about this is that it is continuing to promote the broken way of specifying header files in Arduino
so it doesn’t help solve the ambiguous library selection process when there are library header file collisions since the header files included in the code are not explicitly specifying the library.

i.e. if the include path were to include all the library directory locations in the proper order,
(there are only about 6 or so of them and they never change for a given architecture)
then sketches and libraries could explicitly specify the desired library for the header files.

so for example instead of just specifying <SPI.h> which is ambiguous as to which library, the full include would be
<SPI/SPI.h> which specifies that the header is coming from the “SPI” library since it will be coming from a library
in a directory named “SPI”.

Also, libraries that need to use other libraries would not need to have the needed library directory added to the include path
if the include path specified all the to level library directories and the library used the full include like <SPI/SPI.h>
(it would be required for the needed backward compatibility)

The problem then reduces to how to select which libraries to build and include which comes down to parsing the include
header file nams to look for header files that match header files in library directories.

The reason I bring this up is that libraries are a bit different than sketches and it would be nice to start moving in a direction that starts to help solve the ambiguous library collision issue.

So my request would be to have the code that parses for libraries support both forms of includes.
<SPI.h> (for backwards compability)
<SPI/SPI.h> (to be recommended to library writers moving forward)

and by looking for both forms of includes when looking for and parsing for library headers.
It also requires adding the include paths for the all the root library directories in the proper priority order.
(there are only about a maximum of 6 or so of them for each architecture)

That way at least moving forward, new code could explicitly specify which library the header file is
to come from.

— bill