Assuming a separated export file for every install component.
In the book “Professional CMake” it’s suggested, as a recommended practice, that consumable projects should let users install runtime only components (binaries) separately from development ones (headers, ecc).
Some chapters before, it’s said that config files, other than solving inter-component dependencies, must also check if the required components have actually been installed in the system.
For example, some explicit code is needed to make sure the runtime component is installed when requested by a find_package()
call, and the same thing for the development one.
The the book provides the following snippet:
cmake snippet
# Work out the set of components to load
# Ensure Runtime is included if Development was given <...>
# No components given handling <...>
set(comps ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS})
# Storing comps in a safer variable name.
set(${CMAKE_FIND_PACKAGE_NAME}_comps ${comps})
# Find external dependencies <...>
# Check all required components are available before trying to load any
foreach(comp IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_comps)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED_${comp}
AND NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/MyProj_${comp}.cmake)
set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
"MyProj missing required component: ${comp}")
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
return()
endif()
endforeach()
(I cannot explain why using two names for the same value, comps
and ${CMAKE_FIND_PACKAGE_NAME}_comps
, if comps
is “usafe”, why bothering with it?)
The script checks if the requested components are installed by checking if the corresponding export file exist.
This works only for components that include an exported target. If I were to apply the aforementioned recommended practice, the “development” component would fail the check, because it exports no targets.
“Dummy” export sets aren’t allowed by cmake, it complains about the export set being undefined. I get that export files’ only job is to define imported targets, but perhaps their role is more than that: they are a convenient and automatic way to tell which component/export set has been installed.
My current solution would be to force the creation of an empty export set with an install script, but that looks very wrong. What could I do?
Another approach would be to generate the config file at install time, and write down which components are being installed. But even if an (install time)variable with that data existed, for some reason the cmake --install --component <comp>
has been designed in such a way that installing multiple components at a time is impossible!
It makes absolutely no sense. It is possible to install multiple components without problems, if they are part of ALL
, isn’t it? Why can’t they be installed explicitly?