In modern CMake, it is customary to export targets within namespaces, e.g. have your foo
project export foo::foo
and perhaps also foo::bar
etc.
My question is: Do these namespace actually mean anything by themselves, or are they just parts of a single name, without CMake separating the ::-separated name components?
And if the former is true, can you say things like "all targets in a namespace" or otherwise use the namespace as such?
I did not see any CMake functionality (yet) that would allow handling the name components of namespaced export targets separately. But I found that CMake namespaces still have one meaning, influencing the behavior of CMake:
Using target names containing ::
in a target_link_libraries(…)
call will ensure that CMake resolves this only to so-called IMPORTED targets that are found via find_package(…)
. It prevents the usual fallback mechanism to also try resolving this as a library filename on disk (like where -lName
would look for libName.so
on disk).
That behaviour is documented in CMake Policy 0028. It is not necessarily enabled everywhere, but CMake ≥3.0.2 will warn if not.
It's also useful. I just had a confusing issue caused by CMake's fallback behavior (see). As a consequence, I'll strictly use namespaced target names with ::
in target_link_libraries(…)
.
Sadly, from another piece of CMake documentation, it appears that this feature of identifying IMPORTED targets is probably the one and only meaning of CMake namespaces:
A
NAMESPACE
with double-colons is specified when exporting the targets for installation. This convention of double-colons gives CMake a hint that the name is anIMPORTED
target when it is used by downstreams with thetarget_link_libraries()
command. This way, CMake can issue a diagnostic if the package providing it has not yet been found.
At first glance, it seemed to me that there is one namespace per CMake package and one target name in that namespace per package component. So that after a find_package(noms COMPONENTS fruit veg)
you'd have noms::fruit
and noms::veg
available for target_link_libraries(…)
. But that is only a widespread (and useful) current practice. Technically, package components do not necessarily map to one target though (details).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With