Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do CMake namespaces actually mean anything?

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?

like image 359
einpoklum Avatar asked Nov 06 '22 09:11

einpoklum


1 Answers

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:

Namespaced targets are never filenames

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 an IMPORTED target when it is used by downstreams with the target_link_libraries() command. This way, CMake can issue a diagnostic if the package providing it has not yet been found.

Package components are a different thing

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).

like image 127
tanius Avatar answered Nov 16 '22 09:11

tanius