I have a project which uses the Boost library through the target Boost::headers . I really like the idea of CPS and I would like to use it to install the project. But I encountered a configuration error:
CMake Error in src/CMakeLists.txt:
Target "mps" references target "Boost::headers", which comes from the
"boost_headers" package, but does not belong to the package's canonical
namespace ("boost_headers::"). This is not allowed.
I knew from the post that CPS enforce the package name must be exactly the same as namespace. But widely used C++ libraries like Boost don’t follow this rule and this makes the adoption of CPS extremely difficult.
Is there any way to go around this error, without giving up on CPS or Boost::headers?
Thanks very much
Versions
CMake version: 4.3.0
Boost version: 1.90
Code
find_package(Boost REQUIRED CONFIG)
# ...
target_link_libraries(mps PUBLIC Boost::headers)
install(TARGETS mps EXPORT mps FILE_SET publicHeaders)
install(PACKAGE_INFO mps EXPORT mps VERSION 1.0.0)
Yes, by CPS I meant Common Package Specifications, introduced in CMake 4.1.
And what is your problem?
I have a project which uses the Boost library through the target Boost::headers . I really like the idea of CPS and I would like to use it to install the project. But I encountered a configuration error:
CMake Error in src/CMakeLists.txt:
Target "mps" references target "Boost::headers", which comes from the
"boost_headers" package, but does not belong to the package's canonical
namespace ("boost_headers::"). This is not allowed.
There’s no solution here. The incompatibility is intentional. Having packages namespaced by anything other than the package name was a possibility opened by the original CMakeConfig mechanism.
This possibility made further innovations extremely difficult. Not being able to derive which package a component belongs to from the name the user provides when the want to use it means we always need the redundant find_package() followed by target_link_libraries.
We would never be able to design the obviously desirable interface, which is allowing a target to state: “I require boost::whatever”, and the build system automatically figures out how to find boost and provide the whatever component.
CPS wants to fix that, if it left the hole open it would never be able to. So it shut the door on the mechanism used by the old CMakeConfigs.
There’s a partial backwards compatibility with the old configs, if they use the correct naming mechanism and don’t do anything fancy CPS can use them automatically, but that compatibility is easy to break and using a different namespace than the package name is one way to break it.