You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you have multiple build_types and the generated pkg-*-data.cmake have different dependencies, it is possible that a Debug build cannot find its dependencies.
This issue is often not too important, as most of the time you will have, e.g., a cmake_layout and thus separate generator directories for each build_type. In our case, we have a slightly special setup where we copy all generated files into a common cmake folder which is then shipped to our developers in a full installer of the build environment.
Thanks to the generator expressions and careful selection of list appends inside the generated files, this is a great way to get them up to speed with all conan recipes, but we realized an issue for conditional dependencies:
If a conanfile has no dependencies in the release config, but a dependency in the debug config, and the *data.cmake files are inside the same ${CMAKE_CURRENT_LISTS_DIR}, the *-release-*-data.cmake file will reset the _FIND_DEPENDENCY_NAMES causing CMake to fail to find the proper targets.
Operating System+version: Linux (Ubuntu 22.04), MacOS (Sonoma 14.3.1) (but should also apply for other OSs, it's a template issue)
Compiler+version: Any / irrelevant (CMake issue)
Conan version: 2.1.0
Python version: 3.10, 3.11 (any, should be irrelevant)
Steps to reproduce
Create three conanfiles:
pkg_a (for illustrative purposes a debug only library, say a debugger)
pkg_b depends on pkg_a if build_type=Debug, but not for build_type=Release (this is the crucial bit)
and will get all the relevant CMake files.
These CMakeFiles could now be used without conan, but they come with a slight twist.
Using find_package(pkg_b) will actually fail in Debug mode with this error (well, there is another error about missing include dirs in pkg_b, but that's irrelevant for this issue):
CMake Error at pkg_b-Target-debug.cmake:15 (set_property):
The link interface of target "pkg_b_DEPS_TARGET" contains:
pkg_a::pkg_a
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
Call Stack (most recent call first):
pkg_bTargets.cmake:24 (include)
pkg_b-config.cmake:16 (include)
CMakeLists.txt:4 (find_package)
You can reproduce this with this pkg_c/CMakeLists.txt inside pkg_c's directory:
# from debug-data
list(APPEND pkg_b_FIND_DEPENDENCY_NAMES pkg_a)
list(REMOVE_DUPLICATES pkg_b_FIND_DEPENDENCY_NAMES)
# from release-data
set(pkg_b_FIND_DEPENDENCY_NAMES "")
This in turn causes the find_dependency(...) loop in pkg_b-config.cmake to not find anything in either build_type and thus not declaring the target pkg_a::pkg_a properly; still, the debug configuration attempts to link against it in pkg_b-Target-debug.cmake:
A possible fix could be to not use set(pkg_b_FIND_DEPENDENCY_NAMES "") inside the corresponding templates, but instead rely on the append mechanism as well, simply appending an empty item:
list(APPEND pkg_b_FIND_DEPENDENCY_NAMES )
Manually patching the CMakeFiles like that inside the generator step fixes this for our use-case right now, but I haven't checked the CMake-list-append-behavior thoroughly enough to see if that's a good fix.
If this is indeed a bug and should be fixed, I will happily change the template with a PR, so let me know if you want to change that or if it works as intended.
Logs
CMake Error at pkg_b-Target-debug.cmake:15 (set_property):
The link interface of target "pkg_b_DEPS_TARGET" contains:
pkg_a::pkg_a
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
Call Stack (most recent call first):
pkg_bTargets.cmake:24 (include)
pkg_b-config.cmake:16 (include)
CMakeLists.txt:4 (find_package)
The text was updated successfully, but these errors were encountered:
Thanks very much for your report, and specially for the detailed instructions to reproduce. That helped a lot.
I think your research is correct, and that doing the APPEND was the originally intended way, and it could have been than it has worked for other cases just because the inclusion order was different and the APPEND happened after the set().
I am submitting it as a potential fix in #15853, hopefully for next release.
I especially like the condensed version of the issue in the conditional build type test, it demonstrates the issue really well. Thanks for looking into this and providing such a quick (potential) fix!
Environment details
If you have multiple build_types and the generated pkg-*-data.cmake have different dependencies, it is possible that a Debug build cannot find its dependencies.
This issue is often not too important, as most of the time you will have, e.g., a cmake_layout and thus separate generator directories for each build_type. In our case, we have a slightly special setup where we copy all generated files into a common cmake folder which is then shipped to our developers in a full installer of the build environment.
Thanks to the generator expressions and careful selection of list appends inside the generated files, this is a great way to get them up to speed with all conan recipes, but we realized an issue for conditional dependencies:
If a conanfile has no dependencies in the release config, but a dependency in the debug config, and the *data.cmake files are inside the same ${CMAKE_CURRENT_LISTS_DIR}, the *-release-*-data.cmake file will reset the
_FIND_DEPENDENCY_NAMES
causing CMake to fail to find the proper targets.Steps to reproduce
Create three conanfiles:
pkg_a/conanfile.py:
pkg_b/conanfile.py:
pkg_c/conanfile.py:
We can run:
and will get all the relevant CMake files.
These CMakeFiles could now be used without conan, but they come with a slight twist.
Using find_package(pkg_b) will actually fail in Debug mode with this error (well, there is another error about missing include dirs in pkg_b, but that's irrelevant for this issue):
You can reproduce this with this pkg_c/CMakeLists.txt inside pkg_c's directory:
cmake_minimum_required(VERSION 3.15) project(pkg_c CXX) find_package(pkg_b) message(STATUS "${pkg_b_FIND_DEPENDENCY_NAMES}") add_executable(pkg_c hello.cpp) target_link_libraries(pkg_c pkg_b::pkg_b)
Oh, and the pkg_c/hello.cpp:
Now a call to cmake will fail with above error, if the build type is Debug:
but "succeed" (minus the include errors) with build type Release:
Cause
The problem is that pkg_bTargets.cmake globs for the files:
which includes the files in alphabetical order:
which, in turn, eventually translates to:
This in turn causes the find_dependency(...) loop in pkg_b-config.cmake to not find anything in either build_type and thus not declaring the target pkg_a::pkg_a properly; still, the debug configuration attempts to link against it in pkg_b-Target-debug.cmake:
Fixes
A possible fix could be to not use
set(pkg_b_FIND_DEPENDENCY_NAMES "")
inside the corresponding templates, but instead rely on the append mechanism as well, simply appending an empty item:Manually patching the CMakeFiles like that inside the generator step fixes this for our use-case right now, but I haven't checked the CMake-list-append-behavior thoroughly enough to see if that's a good fix.
If this is indeed a bug and should be fixed, I will happily change the template with a PR, so let me know if you want to change that or if it works as intended.
Logs
The text was updated successfully, but these errors were encountered: