[cmake-developers] Unknown Imported & Global libraries

Florent Castelli florent.castelli at gmail.com
Mon Jan 9 19:00:11 EST 2017


> On 9 Jan 2017, at 20:55, Brad King <brad.king at kitware.com> wrote:
> 
> On 12/21/2016 07:12 AM, Florent Castelli wrote:
>> find_package(foo)
>> if(NOT FOO_FOUND)
>>  add_library(foo STATIC foo.cpp)
>> endif()
> 
> Instead do
> 
>  find_package(foo)
>  if(NOT FOO_FOUND)
>    add_subdirectory(bundled_foo)
>  endif()
> 
> so that the imported targets are visible.  Inside the bundled_foo you can build
> the target and then crate an ALIAS library whose name matches what the imported
> target would have been.
> 

The problem with that approach is that it’s up to the “caller” to put that boilerplate and it would be much nicer to have all of that in the callee, all within the same script.
Additionally, all the bundled library are usually setup in another folder “ext”, “vendor”, “3rdparty” which will be a different context and won’t make those available to the rest of the code.

>> make imported libraries global by default
> 
> The reason they are locally scoped is that find_package() may load
> different, possibly conflicting, external packages in separate directories.
> The find_package() call should be made at the highest level that contains
> anything that directly references the target.  See above example.
> 

If the libraries don’t come from a find_package() call but my code, it should be my responsibility to make sure there’s no 2 conflicting libraries with the same name.
If I can guarantee that, then that is an annoying restriction on imported targets. 

> An alternative is:
> 
>  find_package(foo)
>  add_library(Foo INTERFACE)
>  target_link_libraries(Foo PUBLIC FOO::FOO)
> 
> That will make a globally visible Foo target that when used forwards all
> usage requirements from the imported target.
> 

That’s another approach I’m considering. It’s just annoying that “FOO::FOO” becomes reserved as I’d rather have the external libraries “namespaced”, and I can’t redefine an alias.
I guess I could set their name to Ext::FOO::FOO instead which would be decent.
Again, that’s some more annoying boilerplate.

Note it should also be INTERFACE and not PUBLIC in there.

> -Brad
> 

Anyway, this still doesn’t explain why “UNKNOWN IMPORTED” and “GLOBAL” keywords don’t work with each other. My guess is they should under a controlled setup, but I couldn’t make it work.

/Florent


More information about the cmake-developers mailing list