<MyPackage>Targets.cmake referencing configurations that don't exist anymore

Hi,

Targets.cmake is default generated with following code:

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

# Cleanup temporary variables.
set(_IMPORT_PREFIX)

# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
    if(NOT EXISTS "${file}" )
      message(FATAL_ERROR "The imported target \"${target}\" references the file
   \"${file}\"
but this file does not exist.  Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
   \"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
    endif()
  endforeach()
  unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)

I encountered many times the following situation: I’ve got <MyPackage>Targets-debug.cmake and
<MyPackage>Targets-release.cmake on my drive but one of the associated target (let say MayPackage.lib in debug mode) does not exist anymore.

I have now an application, in release mode, that find_package(MyPackage). This fails with error:


The imported target “MyPackage::MyPackage” references the file
“MyPackage/libs/Debug/MyPackage.lib”
but this file does not exist. Possible reasons include:

1- How can I prevent my release configuration to fail due to the lack of an unrelated dependency (the debug version)?
2- How can I remove a configuration (binary and *.cmake file or *.cmake file only if the binary has been removed accidentally) in a clean way (so far I have to manually suppress <MyPackage>Targets-debug.cmake for instance)?

Thanks

It looks like you installed into a “dirty” install tree that previously had a debug build in it. CMake includes configuration-specific files using a glob, so if a debug build had installed its files previously and weren’t fully cleaned up, references like that may still exist.

The only reliable way is to remove the install tree and reinstall things into it. You can probably just nuke the package’s CMake directory and rerun its install for this though.

I’m not sure to get the point.

My package *.cmake files are in a single directory (that acts as a registry for all my package).

My install trees are “elsewhere” (Actually, I’ve got one per package, with separate directories for each configuration).

My purpose is to have a single path to give to CMake for being able to find all my packages, whereas my binary are actually properly organised.

Is it a bad way to go?

I would have thought that a “smarter way to go” would be not to issue an error but merely a warning when the binary referenced by the package is missing and letting the error happen only if it is actually the required version. For instance, when calling find_package, the build type is known and when “globing”, unrelated build configuration could be ignored?

May be a smarter heuristic may be necessary to tell if you accept a fallback (linking a debug library with a release application if it suits your needs).

A.

Not really as there’s no defined build type for multi-config generators and the currently-built configuration may be different than any of the available configurations. Maybe MAP_IMPORTED_CONFIG-like variables could be used, but that seems tedious. It seems easier to just refresh the install tree when installing a dependency (especially if you have per-package install trees like you say).