find_package(CONFIG) should call find_package() recursively on its own dependent targets
I have a project which builds 2 shared libaries (DLLs on Windows in fact), A and B, which are exported and installed to two separate folders with their own (A/B)Targets.cmake and (A/B)Config.cmake files to allow find_package()
to find them. B depends on A via target_link_libraries()
. I have a separate project, C, which builds an executable which calls find_package(B), and CMake fails to generate the build with the error: The following imported targets are referenced, but are missing: A
. If I call find_package(A)
from C before calling find_package(B)
then everything works correctly, but I would rather not in general have to manually identify relevant dependencies of B from C and call find_package()
on all of them. Looking in the generated BTargets.cmake file I identified the following code as the source of the problem:
foreach(_target "B" )
if(NOT TARGET "${_target}" )
set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets} ${_target}")
endif()
endforeach()
If I replace the set()
call with a find_package(${_target} REQUIRED)
call then everything works correctly (and if the package is not found then CMake still correctly fails, albeit with a different error message). Is this a reasonable modification to the code generated via install(TARGETS B EXPORT BTargets.cmake)
? The relevant code seems to be in cmExportFileGenerator.cxx
around line 1132. Is there any reason not to do this? It will not change the behaviour in cases which would have succeeded previously, but are there any cases where this could do the wrong thing and pass a build when it should fail?
I guess that it might be better to try and keep the existing error message if the package is not found, as it gives more context to the user, but that is an implementation detail.