ALIAS and (not) globally visible targets

I’m getting an error with CMake 3.16.3 that is not failing in 3.24. The code is working around a legacy construct of created imported targets when the package already has imported targets. So rather than create an imported target, I’m creating an alias target:

if(TARGET ${_target})
    add_library(My::target ALIAS ${_target})
endif()

As noted, CMake 3.24 does what I want. However, CMake 3.16.3 gives this error:

#5 2.423 CMake Error at cmake/Modules/FindFoo.cmake:195 (add_library):
#5 2.423   add_library cannot create ALIAS target "My::target" because target
#5 2.423   "Foo::target" is imported but not globally visible.

I found this note on Imported Targets:

The scope of the definition of an IMPORTED target is the directory where it was defined. It may be accessed and used from subdirectories, but not from parent directories or sibling directories. The scope is similar to the scope of a cmake variable.

It is also possible to define a GLOBAL IMPORTED target which is accessible globally in the buildsystem.

I must confess, I don’t really know what that means; What is the directory of my cmake/Modules files? Is it the top-level CMakeLists.txt where it is included?

I tested the IMPORTED_GLOBAL property of the imported target, and it is FALSE

Package Foo is not setting the GLOBAL property when it creates the IMPORT target.

This error seems to suggest that I can’t do what I want, but it does work in later CMake. Is there a work-around so it isn’t an error in older CMake?

I tried that with pugixml when it changed its target names. Here’s the result that ended up working:

That’s a lot simpler than where I was headed. I extracted the properties from the “real” target and added them to my faux target.

The properties I found I needed to get working included:

  • INTERFACE_COMPILE_DEFINITIONS
  • INTERFACE_COMPILE_FEATURES
  • INTERFACE_INCLUDE_DIRECTORIES
  • INTERFACE_LINK_LIBRARIES
  • IMPORTED_LOCATION
  • IMPORTED_SONAME

If it works like I think (hope) it does, by just creating the “indirection” of link libraries on the “real” target, all those properties will be pulled from the underlying target?

INTERFACE linking can be thought of as “if you link me, link this too”. So it acts like an ALIAS for compatibility purposes.