I'm familiar with language C, therefore I was on the wrong way what #include in Arduino IDE exactly means and where to store the needed data. I had to consult more than one documentation to be clear, that the #inlcude loads also cpp source code. Second, that there has to be exist a subdirectory in "arduino/libraries/" with exact spelling as the used <filename.h> name (with capitals respected and without the appendix .h). I think this should be emphasized in documentations for absolute beginners. I'm a retired experienced mainframe systemsprogrammer, but you see, not only novices face such problems. I think it's probably the phenomenon when technichians write such documentation and presume that such meanings of #include known by most users.
#include is a full part of the C++ language that you use when you code for your Arduino. see Source file inclusion
the IDE adds a layer to this and identifies all the files from the selected library which need to be compiled and link with your code.
J-M-L, that's the explanation, what I missed: "the IDE adds a layer" and this #include works a little bit different to the known #include in c or c++. In the *.ino code #include is the cpp-code, which again has an #include, and thats in the known layer, how #include in c and c++ works. That confused me, to distinguish the #include for c++ and the #include for the IDE.
It’s a bit different than this.
#include just injects the file as it exists (from the libraries directory if you used angle brackets <> for the name or from the local directory (and if not found the libraries) if you used double quotes "")
What the IDE adds is other targets to the compilation and link.
For example if you #include <SoftwareSerial.h> then this file is injected in place and all the files in the library src directory are added to the compilation (here just SoftwareSerial.cpp)
So it’s kind of like the IDE builds dynamically a makefile from looking at what you use and inferring other source files to compile, trying to be smart at what makes sense when the include might be ambiguous
Most of the included *.h file contains *.cpp and *.h files. Are both files not appended at the top of the source codes?
Not to my knowledge, only the .h
I think it's really separate compilation and linking but the .ino get a bit massaged before being compiled (prototype generation, all the .ino are merged etc)
#include in Arduino sketches works the same as #include works in C/C++ (Arduino sketch code IS C++ code) and the c pre-processor works the same way it has worked for decades - no differently than the way it worked long before Arduino existed.
The IDE is big wrapper around gnu gcc tools that attempts to do some things for the user in the name of trying to make things "simpler".
Things like auto generating function prototypes.
One of the areas where I think they made a wrong turn years go is in how Arduino "libraries" are handled. There were other ways to handle it that would have eliminated some of the issues, especially those relating to name and header file collisions.
The only true Arduino library used by the IDE is the Arduino core library. All the other Arduino "libraries" are just source code in directories that are compiled as needed and linked in.
The IDE will look at the header files you include in your .ino file and try to guess which "library" that header comes from.
It adds the directory location of a library that it guesses you are using to the include path for the c pre-processor so that it can be found.
It has a set of rules it uses to determine which library and directory to use when there are name collisions (multiple choices) for a header file.
Then it compiles and links in the code for the "library" it assumed you needed, but it doesn't actually every create a library from the Arduino "library".
--- bill
The included file usually has two files -- *.h file and *.cpp file. The *.h file contains the function prototypes against which the syntaxes of the functions/methods of the sketch are checked and then the *.h file is expelled. If this information is correct, then why should the IDE be still generating the function prototypes?
The .cpp file provides the definitions of the available functions/methods. The IDE/compiler picks up only those functions/methods which have been used in the sketch.
That’s more likely done at the linker / optimizer stage rather than IDE and compiler
Not necessarily.
It depends on several factors.
If using templates, i.e. a templated class, the code must be in the .h file that is included by all the modules that use the class.
As @J-M-L mentioned the removal of unused code (functions) is handled by the linker, but the compiler is also involved as it tags the functions so that the linker can see which ones are not used. But the compiler and linker have to be told to this - it is not the default.
Also, if using virtual functions, you will get the virtual function linked in regardless of whether code was ever called/used.
There used to be a way to patch the vtable entries to avoid this but more recent versions of gcc have removed this capability.
--- bill
I'm not sure about the "absolute beginners" part of your proposal, but it might be worth considering making the information J-M-L shared more accessible.
This system is documented here in the site for developer-targeted documentation:
https://arduino.github.io/arduino-cli/latest/sketch-build-process/#dependency-resolution
The user-targeted documentation is here:
https://www.arduino.cc/reference/en/language/structure/further-syntax/include/
Although that certainly happens, I don't think it is the case here. The user-targeted documentation is intentionally written to be very approachable to everyone. Part of that comes from, omitting any unnecessary technical details.
All the beginner (and even likely intermediate users as well) needs to know is that if they want to use the capabilities of a library in their sketch, they must add the #include directive for the appropriate header file. The underlying mechanisms of the Arduino build system that make that possible are not of interest to these users and pushing it on them would only make the learning curve steeper.
But certainly it is fine and expected that some will want to understand more about how things work under the hood. Efforts should be made to make that information discoverable in a manner that doesn't have a harmful effect on the approachability of the documentation.
If anyone would like to propose enhancements or fixes to the Arduino Language Reference content, it is hosted in an open source public repository here:
More information about that here:
One of the things not mentioned on the dependency resolution is what happens when the name collision is between a library header file and a system header file.
Here is a realworld example.
#include <Time.h>
Windows by default does not take case into consider in filenames.
This means that Time.h and time.h are effectively the same.
(The IDE could case check when doing its searching, but it doesn't - that is another issue/bug)
time.h is a system header file that now comes with the gcc toolset on most Arduino platforms.
The question becomes on Windows, will the IDE use Time.h from the Time library or time.h from the system libraries or get confused?
And the answer is......
It depends on which platform you are using since the platform.txt rules are inconsistent on where the system header files are in the command line when calling the compiler.
The result is it usually doesn't work on Windows but can fail in different ways.
--- bill
ptillisch, with absolute beginners I mean beginners with Arduino. Due to the discussion now I can review my way in the wrong direction. I tried the "Hello world" example with blink.ino. Next step I tried to run an example, that has an #include in the sketch. At this time I was not aware of the role of this #include. Shure I looked for files that contain the needed stuff. But I wasn't aware what part or subdirectory has to be stored in arduino/library. In my brain I focused at the #include as used in C or C++. And this different impact to #include in *.ino I think should be emphasized in documentation for beginners, probably mention the different coding blink.ino and an extended example with c++ coding in one documentation file.
It's mentioned anywhere and at least, I found it.
I'm not sure what you mean by that. #include does work the exact same way as in C or C++
what's different, as explained before, is that you don't have to manage a makefile and that the IDE infers from what you include the rest of the code needed
I mean, I expected with an #include statement used in C, that #define, #ifdef, #ifndef, function declarations and so on are loaded. For example I experimented with a sketch named "DallasTemperature" from an Arduino kit with accompanying book. The according library provided by the kit vendor contains a .cpp, a .h, keywords.txt, library.json, library.properties. I think I would had an earlier notion what an Arduino IDE #include expects, when for including such stuff another statement were used, such as #inclarduino. For me it's clear now, what's going on and it's not necessary to continue the discussion, except when there are more questions by other newbees. I hope my conversational english is not to bad. I'm german, and sometimes it could be that I use a phrase, that I think it's funny, but it could be that native english speakers understand it different. ![]()
I'm a non native speaker, so no worries ![]()
So I guess you wanted the Arduino team to add a specific directive to differentiate between an include that does not add anything to the compilation list and one that does ?
I'm not seeing the gain from a developer perspective (rather adds complexity where it's not needed since the IDE can do the heavy lifting identifying if it needs to add stuff to the project)
I don't understand what you are trying to say.
#include works exactly the same in C, C++, and the with Arduino .ino files.
--- bill
That's what it does.
The #include in the sketch works exactly like it does in an ordinary C program.
In ADDITION to the normal behavior, the IDE will also:
- Check the name of the include file against the list of standard and installed libraries.
- If there is a match, the library source directory will be added to the search path for include files in the compiler commands (eg
-I/Applications/Arduino-1.8.15.app/Contents/Java/portable/packages/arduino/hardware/avr/1.8.5/libraries/SoftwareSerial/src) - If there was a match, make sure files of the library get compiled for your particular board. (they'll usually be in the same directory as the .h files.)
- If there was a match, add the list of compile library files to the linker command for the sketch. (
-l/tmp/Arduino1.8.15Build/libraries/SoftwareSerial/SoftwareSerial.cpp.aor equivalent) (actually, I think Arduino normally just adds all the .o files to the link command without making an actual library. Other link options cause only the used functions to be present in the final binary. But it does permit libraries containing only .a files...)
None of this affects the operation of the #include itself.
On a "normal" unix system, (1) wouldn't happen, 2 and 4 would be done by manually changing the Makefile (or equivalent), and 3 would have to be done manually "once" (and thereafter the library would stick around in a standard place in binary form.) (Many embedded cross-compiling IDEs include something similar to the Arduino IDE functionality, because manually adding paths like the ones in (2) and (4) is annoying and error-prone.)
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.