Clarify note "export name that is the same as the package name" in cmake documetation

cmake install man page:

Note: The installed <export-name>.cmake file may come with additional per-configuration <export-name>-*.cmake files to be loaded by globbing. Do not use an export name that is the same as the package name in combination with installing a <package-name>-config.cmake file or the latter may be incorrectly matched by the glob and loaded.

Assuming the “export name” is value of <export-name> in the install(TARGETS targets EXPORT <export-name>...) … command. It is used to specify the export file in subsequent call to install(EXPORT <export-name> ... FILE <name>.cmake ), where name could be set as the value of <export-name> to create filename referred as <export-name>-*.cmake. Then what is meant by “installing a <package-name>-config.cmake file” ? Which command it is created with ? I don’t see any reference to <package-name> in the guide.

Is this relevant to generation of xxxTargets.cmake and xxxTargets-debug.cmake (assuming Debug BUILD_TYPE) and configure_package_config_file() behavior ?
Specifically the way xxxTargets.cmake includes xxxTargets-debug.cmake:

# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/xxxTargets-*.cmake")
foreach(f ${CONFIG_FILES})

I wonder how to avoid such inclusion and tried removing CONFIGURATIONS options from install(TARGETS xxx ...) option list, but cmake still generates xxxTargets-debug.cmake (matching xxxTargets for this include)


The export filename (install(EXPORT … FILE) or export(EXPORT … FILE)) is usually named with a -targets or Targets suffix. If you do not add such a suffix, the globbing mechanism is likely to include files recursively.

The find_package(SomeName) command will look for a file called SomeNameConfig.cmake (and also somename-config.cmake, but let’s ignore that for now to keep things simple). The contents of that file can be trivial or complex, depending on the project, but one of the things it will usually do is include() the file generated by install(EXPORT). You are responsible for writing and installing the SomeNameConfig.cmake file, it is not something that CMake generates for you.

In very simple projects, sometimes people take a shortcut and they override the default name that install(EXPORT) uses and make it write directly to SomeNameConfig.cmake. I wouldn’t generally recommend doing that, since you almost always end up needing to add additional things later (e.g. calls to find_dependency()).

Since you mentioned in another thread that you have my Professional CMake book, take a look at Section 26.7.1: Config Files For CMake Projects which talks about this topic. For the benefit of others, here’s an example from that section:





install(EXPORT MyProj_Runtime
    NAMESPACE MyProj::
    FILE MyProj_Runtime.cmake
    COMPONENT MyProj_Runtime

install(EXPORT MyProj_Development
    NAMESPACE MyProj::
    FILE MyProj_Development.cmake
    COMPONENT MyProj_Development

install(FILES MyProjConfig.cmake

In your question, you ask "what is meant by “installing a <package-name>-config.cmake file”. The last install command in the above is what that corresponds to. I mentioned earlier that find_package() looks for both SomeNameConfig.cmake and sometime-config.cmake. The CMake docs for install() are using the latter form, but both are equivalent. I tend to find that SomeNameConfig.cmake is perhaps a little more common, so I stick with that form myself.

Great, yes I agree the file passed in the FILE options of install(EXPORT …(or default <export-name>.cmake file) is the list of targets (MyProjTargets.cmake) for use by consuming project to import these targets. It is not project package Config (e.g. MyProjConfig.cmake) file which is used(being searched for) by find_package() when it is called from consuming project. I understand that MyProjConfig.cmake has include(MyProjTargets.cmake) and xxxTargets.cmake has include(MyProjTargets-debug.cmake). This makes Craig’s example in 5th edition confusing as it passes MyProjConfig.cmake as FILE in install(EXPORT.:

install(EXPORT myProj
  FILE MyProjConfig.cmake

However Craig’s comment here clarifies this so could you please confirm the following reading of the NOTE of cmake documentation:
Both <export-name>.cmake(list of targets file aka MyProjTargets.cmake) and <package-name>-config.cmake (find_package searched file aka MyProjConfig.cmake) have to be installed typically using install(FILES command. The <export-name> filename should not match <package-name>-config which means these 2 files must have different filenames. The simple case of naming MyProjTargets.cmake MyProjTargets.cmake meets this requirement bc suffixes are different. However Craigs example in the 5th edition contradicts this requirements which could result in the following problem: find_packages searches for xxxConfig.cmake and finds MyProjConfig.cmake, but inside this file there is include(MyProjConfig.cmake) as it includes target list. Right?

Two paragraphs after that example, it says it isn’t normally done that way, but I’ll add a small note to the example in the next edition to make this clearer.


Yes, except when using the (not recommended) shortcut of using the install(EXPORT) file directly as your <package-name>-config.cmake or PackageNameConfig.cmake file.

Not sure what you mean by this.

No you shouldn’t put include(MyProjConfig.cmake) inside your MyProjConfig.cmake file. In case it wasn’t clear, do not name your export MyProjConfig. Following Ben’s naming suggestion, you’d call it something like MyProjTargets. In the example I posted earlier, I have two export sets and chose to name them MyProj_Runtime and MyProj_Development.

great, thanks.

Sorry, for typo, should be "naming MyProjConfig.cmake MyProjTargets.cmake
I mean that typically Config file has suffix Confg or -config and so it shoujld be easy to avoid using the same name for <package-name>-config.cmake and <export-name>.cmake which is commonly use Targets or -targets suffix

Sorry for typo, in

it should be
find_packages searches for xxxConfig.cmake and finds MyProjConfig.cmake, but inside this file there is include(MyProjTargets.cmake) as including target list inside the template is recommended .
Then MyProjTargets.cmake includes all platform/etc lists matching MyProjTargets-*.cmake template.
This include is generated by cmake