cmake usefulness of aliases
Taking your add_library()
example, the CMake target's name would e.g. directly be linked to the target's output file names.
So ALIAS
targets are mainly used to give the target a more spelling or structured name by e.g. adding a "namespace".
The cmake-developer
documentation gives the following advice on namespaces:
When providing imported targets, these should be namespaced (hence the
Foo::
prefix); CMake will recognize that values passed totarget_link_libraries()
that contain::
in their name are supposed to be imported targets (rather than just library names), and will produce appropriate diagnostic messages if that target does not exist (see policyCMP0028
).
TLDR: It gives other projects consuming yours more flexibility.
To me, the primary motivation for adding an ALIAS is related to installing/packaging and how other projects might use yours. When a project is installed, it can have its targets exported. The two relevant forms of the install()
command are these:
install(TARGETS target... EXPORT exportName ...)
install(EXPORT exportName ... NAMESPACE myNS:: ...)
The first is what installs your actual target (i.e. the binaries), but it also includes the EXPORT
keyword. This tells CMake that this target install is part of the exportName
export set. The second of the above commands then installs a file for the exportName
export set which contains CMake code that creates imported targets for each target in the set. It will prepend myNS::
to all the targets in that set (this is a crucial point for your question). This exported file will be included by the config package file for your project (this is a fairly involved topic, you can get further details on it here). Other projects can then build against your installed project by first doing a find_package()
, which will recreate all your exported targets, except they will now all be prefixed with myNS::
. It then links against these namespaced targets as though they were part of its own build. I'm skipping over a fair bit of detail, but those are the most relevant points to your question.
Now, it may be that the consuming project doesn't want to use find_package()
, but instead it might want to bring your project directly into its build with add_subdirectory()
. This would be a way to build your project from source rather than against a pre-built binary package. It is becoming a much more popular approach since the addition of the FetchContent module in CMake 3.11. If your project has provided ALIAS targets with names that match the exported target name, then the consuming project doesn't have to change any of its target_link_libraries()
commands. Whether it builds against the pre-built binary package or brings in your project via add_subdirectory()
, it links against the namespaced target name (i.e. myLibs::myLibs
in your question) in either case and it all Just Works.
As for what the ::
does, when a name containing ::
appears in a target_link_libraries()
command, it will only ever be interpreted as a CMake target (assuming policy CMP0028 is set to NEW, which it really always should be now). If no such target exists, CMake will fail with an error rather than assume it is the name of a library provided by the system.