I'd like to have a Arduino library that includes a file "Config.h", where every sketch that includes that library would have its own "Config.h".
According to the Arduino documentation (Redirecting), the sketch's directory should always be in the include path:
The include path includes the sketch's directory, the target directory (/hardware/core//) and the avr include directory (/hardware/tools/avr/avr/include/), as well as any library directories (in /hardware/libraries/) which contain a header file which is included by the main sketch file.
When I include "Config.h" in the library, however, it can not find the file in the sketch's directory.
Is this broken, or am I misunderstanding the Arduino documentation?
Create a library that has the line: #include "config.h". Then create a sketch. In the same directory as the sketch, create the "config.h".
The idea is that I want one library (.cpp/.h) that is used by many sketches. The sketches want the library configured slightly differently, however, so I want the library to include a config.h file that is specific to each sketch.
That won't work, because of the way the Arduino build process works. Each library is built in its own sub-directory, and does not "see" files that are part of the sketch. Look at the build directory if you want to see how the build arranges files for each build.
You could include config.h in the sketch before the library include. I use #defines in the sketch before the library include to allow preprocessor configuration of my libraries without the user having to edit the library but only the library .h file can see the #defines. So you could put those #defines in the config.h file. I know it's not quite what you're going for but might be a bit cleaner than having a bunch of configuration #defines in your main sketch file.
pert:
You could include config.h in the sketch before the library include. I use #defines in the sketch before the library include to allow preprocessor configuration of my libraries without the user having to edit the library but only the library .h file can see the #defines. So you could put those #defines in the config.h file. I know it's not quite what you're going for but might be a bit cleaner than having a bunch of configuration #defines in your main sketch file.
That will NOT work with a shared library that is not contained within the sketch directory. NOTHING from the sketch is included in the compilation of a shared library, so putting a #include in the sketch itself has no effect whatsoever on the library.
So where is there an actual library (.cpp) file in there? I see only a .h file. Of course you can include a .h file, but a # define in a .ino file will NOT have any effect on the compilation of a library .cpp file.
I tried this method, but the #define in the .ino before a library's .h was #included did not have any effect in how the library compiles.
I tried with v1.6.4 of the Arduino IDE. What version of the compiler are you using where you see this method works?
I must say this is frustrating. I'm new to Arduino but I've done a lot of embedded C programming. What I'm trying to do is common and useful: I can't believe Arduino limits this.
Believe it. Arduino was created to be easy to use for inexperienced programmers. It was not designed to be the be-all and end-all of programming environments. The build process, quirky though it may be, avoids newbies having to deal with complex make files, which is a MAJOR benefit, and works fine for 99.9% of all applications. For the other 0.1%, you have to improvise.
RayLivingston:
So where is there an actual library (.cpp) file in there?
Maybe we have different definitions of what a library is. To me a library is a way of sharing the same code file with multiple projects by using an #include. SoftPWM happens to have all its code in the .h file. EtherEvent has a .h file and a .cpp file but all the code that relies on the #define in the sketch is in the .h file. I stated multiple times that the #define in the sketch only effects the .h file.
pert:
Maybe we have different definitions of what a library is. To me a library is a way of sharing the same code file with multiple projects by using an #include. SoftPWM happens to have all its code in the .h file. EtherEvent has a .h file and a .cpp file but all the code that relies on the #define in the sketch is in the .h file. I stated multiple times that the #define in the sketch only effects the .h file.
You don't get to make up your own definitions. In Arduino-world, "library" has a very specific meaning - a .h and .cpp file that are compiled separately from the sketch, and joined with the sketch at link time. What you have is nothing more than an include file, not a library. That is NOT what the OP is asking about. Your approach is very limiting, and would not work at all for a true "library".
RayLivingston:
In Arduino-world, "library" has a very specific meaning - a .h and .cpp file that are compiled separately from the sketch, and joined with the sketch at link time.
So I guess the EEPROM library is not a library then? Where is this specific definition of an Arduino library found at?
@RayLivingston what do you think is the appropriate term to use instead of library for the EEPROM library? I apologize to the OP for this getting off topic.
pert: @RayLivingston what do you think is the appropriate term to use instead of library for the EEPROM library? I apologize to the OP for this getting off topic.
You seem to want to split hairs. I would call it simply an include file that happens to define a very simple class. Technically, it could be considered a library, but its single-file structure makes it an exception, rather than the rule. It is very small, with very little functionality, so it is both defined, and implemented, in a single file. For more typical, more complex functions, as in the case of the vast majority of Arduino libraries, that structure is problematic at best. Your solution will work ONLY with very simple libraries like EEPROM which are fully contained in the .h file.
Not at all. I had no intention of starting an argument. I only wanted to learn the correct terminology. I have no formal training in programming so I don't always use the right terms for things which makes searching for information more difficult. Thank you for answering my question. I realize that the system I described is very limiting and I always use a .cpp file in my libraries when possible but I have found this to be useful in some cases. BigBobby didn't give specifics of the library so I thought the information might be useful to them or to someone else searching for a solution. The SoftPWM library is not a great example because their usage of the debug define doesn't really provide any benefit but it could be useful if there were debug prints sprinkled through the code in the .h file. The EtherEvent library is a better, although more complex, example because authenticated usage requires the user to install the MD5 library also. Run time methods of configuring it for non-authenticated usage would still require the MD5 library to be installed even though it isn't used so preprocessor configuration is the best approach. I originally wrote it so that the user would have to comment out the MD5.h include in EtherEvent.h and then the rest of the code is switched with the MD5 library include guard define which allowed the code to be in the .cpp file but this is not very user friendly and is also a pain to have to keep changing it back and forth if you have one sketch that uses authentication and another that doesn't. I think most or all of the EtherEvent functions that are affected by the authentication define are templates so they needed to be in the .h file anyway.
Thank you both for your replies, and no problem with it going off topic.
I understand that the Arduino isn't supposed to be the be-all-end-all for programming environments, and I do appreciate the things they did to simplify the build process.
It wouldn't break their beginner friendly paradigm, however, to simply include the sketch directory in the include path when compiling the libraries. The way their documentation reads, I thought they already were.
Are there really no Arduino libraries that allow configuration by the sketches that use them? If there are some, how are they configured?
I think it would be actually more beginner friendly to allow libraries to be easily configured without requiring the user to edit the library. For many Arduino users a library is just a black box(especially now that Library Manager automates installation), they only need to understand the API.
Here's some interesting reading on attempts to add the feature to the Arduino IDE and the developers' reasoning for not adding the feature: