Using the same namespace for multiple independant projects

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(?)

Thanks.

There’s no rule about namespaces having to match the package name in general, so prog_extA and prog_extB can both use NAMESPACE prog:: just fine.

And Qt does the second part as well (using COMPONENTS to look for the “extensions”).

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?

The namespace is independent of the filename; they don’t have to match.

Hi,
I don’t get it.

According to documentation:
Config mode

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?

Regards,
A.

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.

Hi,

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

Regards,
A.

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.

1 Like