arduino-cmake / Arduino-CMake-NG

CMake-Based framework for Arduino platforms
MIT License
138 stars 39 forks source link

Unsupported header-only libraries when using 'find' API #31

Closed MrPointer closed 6 years ago

MrPointer commented 6 years ago

Currently there's no support for header-only libraries, especially when using the find_library API. The reason for this is that the find_library fails if it doesn't finds any source files, however, that's always the case for header-only libraries, and can be marked as "false-positive".

Solution would be simply to pass an option to the function - HEADER_ONLY, which will hint the framework to ignore sources.

Edit: CMake can't compile nor link header-only libraries, and must use the INTERFACE keyword instead. This leads to a far more complicated solution, which will probably require a separate function.

MrPointer commented 6 years ago

@machadolab I'm completely stuck on this one. I'm testing the feature against the EnableInterrupt library that you pointed out in #28, however, it is such a bad library that I truly don't understand how it even get compiled in Arduino IDE - It's some sort of magic...

The biggest problem is that the header file not only declares functions (such as enableInterrupt), but also defines them! 😱 This leads of course to a multiple definitions of linkage error, since a header file can't define the functions it's declaring - they must reside under a different source file (unless marked as inline, which they're obviously not in this case).

I have absolutely no idea how to solve this, nor how does the Arduino IDE manages to build it successfully.

masha256 commented 6 years ago

Not sure either. I would say just don’t support that mode and encourage people using this project to report to the lib maintainer to properly format their source when it comes up. I doubt many new libs following the 1.5 spec would have this problem.

MrPointer commented 6 years ago

It doesn't really matter if the library conform to the 1.0 standard or the 1.5, since the standard doesn't mention anything about this "style" of source/header files.

Nevertheless, I might've thought about a possible solution, and I think this is probably how the Arduino IDE does it, but it's extremely complicated and would be pretty hard to implement in CMake. The idea is to parse all header files of a library, possibly not only header-only libraries but any type of library, and check whether there are any definitions inside it. If so, physically extract them to a "temporary" source file which will be hidden from the user (It might reside under CMake's build output folder), copy the modified header file to that location as well (as it's not the original anymore) and instruct CMake to refer to those files instead. One of the biggest problems with this approach is the inability of the user to modify something in the library's sources if he'd wanted to - Modifying the original header won't affect the temp "hidden" files, unless there'd be some sort of a link between them, but that's starting to be really messy... It's a pretty ugly solution, and again - Would be extremely hard to implement and maintain, but that's the best I can come up with now, except of course nudging these libraries' maintainers to correct their code.

MrPointer commented 6 years ago

@machadolab BTW, could you find me a good Arduino header-only library to test against? I can create one myself just for testing, but I'd like to test against something that's actually may be used by others