Hi,
Is there a way to use the same namespace accross multiple packages, like:
find_package(prog_extA)
find_package(prog_extB)
target_link_librairies(target PUBLIC prog::extA prog::extB)
Or even, register multiple packages in the same “meta”-package, like:
find_package(prog)
target_link_librairies(target PUBLIC prog::extA prog::extB)
But without the use of the component mechanism, which would require that all extensions are handled in the same CMake project. My goal is to be able to build sub-packages in fully independant CMake projects. And from my understanding, it is not possible with the component mechanism(?)
AFAIU configuration file creation, when I’m creating extA in a namespace prog, I will in fact create some progConfig.cmake, progTargets.cmake and progTargets-<build type>.cmake files. Thus when I will create extB I will overwrite these files and only prog::extB will be visible?
In this mode, CMake searches for a file called <lowercasePackageName>-config.cmake or <PackageName>Config.cmake. It will also look for <lowercasePackageName>-config-version.cmake or <PackageName>ConfigVersion.cmake if version details were specified (see Config Mode Version Selection for an explanation of how these separate version files are used).
Thus as said in a previous comment, adding prog::extB will require to create prog-config.cmake (for instance).
In my use case, all configurations files will be in a single directory acting as a package repository.
But even if I’d use different directories, find_package will stop at the first prog configuration file found?
This is where your misunderstanding is coming from. A target named prog::extB can come from any arbitrary config file. It can come from a file named SillyLongPackageNameConfig.cmake. There is no correlation between package name and target name.
CMake doesn’t “actually” have namespaces, it’s merely a convention. The “namespace” is a string prefix, it has no significant semantic meaning to CMake.
OK but how then does find_package proceeds in config mode to find the correct configuration file.
I always believe (perhaps wrongly) that find_package(<package> COMPONENTS <component>) was looking for a “target” package::component inside packageConfig.cmake?
What I get from your comment is that package and namespace are not related?
with the example in my previous comment, I could make a package progextA (or any other unique name) referencing prog::extA and another progextB referencing prog::extB?
If so, Ben Boeckel comments are making sense now. But I think that actual OP’s use-case would be to be able to find all components of the namespace prog with a single find_package, even if these components come from different projects.
Using his example:
# importing all components of the namespace prog
find_package(prog)
# linking some of them
target_link_librairies(target PUBLIC prog::extA prog::extB)
For instance, let say I want to add an algorithm to an existing (set of) library(ies), how could I do without modifying the original library project ? To be even more specific. If I want to add something to opencv, how can I do that without editing opencv cmake codes and rebuilding it (or at least regenerating the configuration files)?
Components are meaningless to CMake, they are a hint provided to code written by humans. Ie, the handwritten FindPython find-module uses components to figure out if you’re asking for the Python interpreter, the Python development libraries, or both. They have no meaning beyond what the developer of a find module or package choose to give to them, CMake does not automatically generate anything directly related to the COMPONENTS field of find_package().
Correct.
Create a progConfig.cmake file that calls find_dependency() for all the sub packages that you wish to be a part of the meta-package. There is no way to ask “find all the packages that use the string “prog::*” in their target names”. You will have to, as a human, know what set of packages you are concerned with when making the meta package.
As Ben mentioned, it’s traditional to use the COMPONENTS field when creating such a package to know which packages you’re actually interested in. So the author of the progConfig.cmake could write code to check the components list, and only call find_dependency() for packages which map to requested items in the list.