[cmake-developers] Unknown Imported & Global libraries
florent.castelli at gmail.com
Wed Dec 21 07:12:40 EST 2016
In my project, I have to deal with 3rd party libraries. Either the library is available on the system and then I will try to use that, or I will use sources bundled in my repository. This is in order to make Linux maintainers happy who want to have a system-wide shared library, but to also keep a self contained build available by default.
But all that logic is cumbersome, so it usually ends up in a dedicated file looking like:
add_library(foo STATIC foo.cpp)
Then with modern CMake, you don’t just get variables but imported targets, usually defined with something like:
add_library(FOO::FOO UNKNOWN IMPORTED)
All those scripts being used through multiple levels of add_subdirectory() calls, makes it so that the imported targets are only scoped to the leaf file and not visible to the other libraries that may want to use it.
One way to work around that would be to mark them GLOBAL. But the problem is that I then get an error such as:
CMake Error at CMakeLists.txt:1533 (target_link_libraries):
Target “FOO::FOO" of type UNKNOWN_LIBRARY may not be linked into
another target. One may link only to STATIC or SHARED libraries, or to
executables with the ENABLE_EXPORTS property set.
Without the GLOBAL keyword, it links just fine (as long as I keep the definition in the same scope). So why would GLOBAL trigger a different behaviour?
Any ideas why that would be? I went through the code quickly, but I didn’t find anything relevant, so I’m quite puzzled.
I know I could use instead include() instead of add_subdirectory() to go through the external dependencies but I believe that’s a wrong fix. Scoping variables is actually nice.
Also, I would very much desire a setting to make imported libraries global by default to increase the legibility of most code and avoid having huge CMake scripts as most people currently do. Splitting targets in different files should be the norm!
I can also override add_library to add the GLOBAL keyword automatically, which would work if UNKNOWN IMPORTED GLOBAL was actually working...
More information about the cmake-developers