-
-
Notifications
You must be signed in to change notification settings - Fork 388
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
Allow Libraries to Extend Include Path #501
Comments
Please explain why you consider the existing solution of using relative paths to be "not great". |
Relative paths themselves are not the problem (surely they are used in many projects out there) but rather the fact that only the The goal is to be able to include other open-source projects in Arduino libraries without modification - thereby greatly lightening the burden of maintenance. Lets imagine that there are two great projects that should be included in an Arduino library. Their structure is not flat and header files may be located in one or more sub-levels. Each project might have a structure similar to this: - projN
- subA
- headA.h
- subB
- headB.h
- projN.h (#include "headA.h" and #include "headB.h")
- projN.cpp AFAIK there is no way to use this project without modifying it - even if you placed the contents of Maybe it is best practice for a project like Is there another way that I am overlooking? |
Hi @oclyke ,
I'll try to prototype something and let you know 😉 |
Wow fantastic! Can't wait to test drive. I've never worked on the IDE source code but let me know if there's anything I can do to help. |
What does this mean exactly? The environment for include detection and compilation should be as identical as possible, otherwise you might end up with different results and missing includes during include detection? Do you maybe mean that these additional include paths should only be used when compiling source files from the library itself? If so, the include path should be added only for this library's source files, when compiling and when doing include detection I think. However, I'm not so sure this would really work: If the sketch includes a library header file that wants to include a header file from the additional include path, this would break. Because of this, in practice you pretty much always need a single, global, list of include paths used in all compilations.
@oclyke Are you sure this will not work in Arduino? When you include with This does not solve the more complex problem when you have two immutable sublibraries of which one needs to include the other, so the additional include paths can still be useful. On a related note: Maybe it would be interesting to also have an option to not put the |
With #include "foo.h"
#include "bar.h"
void setup() {} Then,
Foo library adds Now, there are a couple of real life things to keep in mind:
Hope it's clearer now, but I'd love this thing to be ready soon and having a larger audience can help in finding the ideal solution. |
@facchinm I'm a bit confused with your example. The sketch includes Furthermore, you seem to suggest a conflict between Assuming that you intended no Your suggestion seems to be to only put
Now, suppose that libbar depends on libbaz and I guess this means the perfect solution does not exist (the problem, really, is that "includes" in C/C++ inhabit a global namespace and can cause conflicts). The traditional way to solve this is to do have a single (or a few) include dir instead of one per library and doing things like Given there will be some limitations either way, I think I would prefer to keep the include namespace simple and flat, and let people deal with duplicate header files (which then need to do already, if multiple libraries provide a |
Sorry for the The main topic was Said that, at compile time the additional include paths must be added (and my PR does exactly that). |
On the main topic (where to include additional_indlude_paths in the build)There's a lot to keep up with between all these posts but I'd like to submit my two cents.
Originally I assumed that this was because the library for You two have brought up consideration of what should happen when a "Library" (meaning one installed via Library manager) and some user files in the Sketch provide conflicting files. I think you two have covered that pretty well and I agree with the statement:
Here are a few little snippets I want to echo / emphasize:
Yes. Let's not add confusion / errors by changing which paths we provide in different contexts.
Maybe I am missing something here? What if there is some immutable code that is written with relative includes that you then include in a subdirectory of your library? (You are prevented from using a flat file structure because you want to use a git submodule, in this example) Maybe I just don't know how proper relative includes are written?
What, though, is 'the current directory' in this case? From my understanding the compiler is operating out of just one directory (which is fairly well hidden - maybe in the installation or the temporary build directory?) and so requires instructions on where to find header files.
Me too! Wondering what exactly you mean though. Does this mean add as a feature to an upcoming release of Arduino and allow users/developers to try it out at large scale? Or does it mean releasing it in a beta build and / or discussing on the developer's email list? About public vs. private APIsYes - to allow |
Includes are done relative to the current file, that is the file that contains the include directive. The "current directory" (in the operating-system sense) is not relevant here, only the directory that contains the file that contains the include. So it does not matter where a file is included from, relative includes are always evaluated in the same way. What can be a bit confusing is that an include with
I'm not entirely sure what you're saying, but I can imagine that we would want to treat include detection specially to e.g. prevent One caveat: If includes in the additional include dirs are not considered for fulfilling missing includes (only added to the path once a library is selected), then that also prevents separating the header files from the src files with a "do not put src/ on the include path" option. OTOH, behaviour could maybe change based on such an option, of course, so maybe not something to influence this decision. |
W00ps, missed @facchinm's last post when I wrote my previous reply.
I'm not sure what you're proposing here exactly, but as suggested in the next-to-last paragraph of my last post, it is important to add the additional paths to the preprocessor commandline once a library is added to the build, otherwise includes of "private" header files on the additional paths might result in missing includes. I think this also the situation you talk about, but I'm not sure how you're proposing to support this (bailing out and halting further include detection makes no sense, since that could mask later missing includes). |
Is this expected to be merged soon? |
I am also interested to know if this feature is still on the roadmap of the Arduino project? The only workaround I found is adding a new entry to the boards.txt of the specific SDK I am going to work with (e.g. Due,ESP32,etc). This is really hacky and does not expand/is not flexible. The disadvantage of the current situation is that each time I have includes in another folder that is not |
Well, it seems that this issue will not be solved in the short term. I have developed a script that easily replaces include directives to relative ones. This should reduce the time it takes to port a 3rd party library to the Arduino ecosystem. LinksBased on this script I easily ported the lwIP TCP/IP stack into Arduino. |
It would greatly benefit library developers if libraries could specify additions to the include path used in their compilation. Developers could then create work that is much easier to maintain.
Problem
In my personal use case I would like to write both a portable C driver for a device (that can be used on other platforms and with minimal overhead) and an Arduino wrapper for that interface that makes it simple to use for beginners. For the purpose of illustration it would be best to think of the portable driver as immutable source code obtained from a third-party. For maintainability the third-party code would be included 'symbolically' (e.g. git submodule). A representative library structure might be:
The file
ossdl.c
will most likely include the open-source portable interface with a line such as:#include "ossdl.h"
-- unfortunately this will not work in Arduino 1.8.10The workaround(s) is(are) not great:
#include "open-source-servo-driver-lib/include/ossdl.h"
inexplicably associates the OSSDL project with Arduino build requirementsProposed Solution
I suggest that library.properties gains a new comma-separated field of extensions to the library's include path (relative to
Servo/src
). If not present (as in the case of existing libraries) onlyServo/src
will appear in the search path - keeping compatibility with the existing codebase. For the sake of interface protection this is as good as the current technique because users would have to modifylibrary.properties
to get access beyond the developer's original intent. Of course if they are modifying the library they don't need this feature to accomplish what they seek.To fix the example situation from above the developer would add the following entry to his
library.properties
file:Of course it would also be valid to use
since commas are not (typically) used in filepaths. If needed another format (or use of escape characters) could be employed.
Other Possible Solutions (thoughts?)
.h
files underneath thesrc/
directory would be accessible. Concerns of interface preservation/enforcement would be raised.Related Issues / Feature Requests
arduino/arduino-builder/issues/15 - A long-debated feature in which it is requested to put the Sketch folder on the include path for libraries. This is not the same request because
The text was updated successfully, but these errors were encountered: