From e23f0748d85a1e3bf9d61bab2ed2affbe84f96a0 Mon Sep 17 00:00:00 2001 From: Taylor Sasser Date: Wed, 3 Sep 2025 14:05:35 -0400 Subject: [PATCH] CPS: Import per-configuration attributes --- Source/cmPackageInfoReader.cxx | 13 +++---- Tests/FindPackageCpsTest/CMakeLists.txt | 8 ++-- .../find_package-CPS/ConfigDefault.cmake | 9 +++++ .../find_package-CPS/ConfigFirst.cmake | 9 +++++ .../find_package-CPS/ConfigMapped.cmake | 14 +++++++ .../ConfigMatchBuildType.cmake | 9 +++++ .../find_package-CPS/RunCMakeTest.cmake | 27 ++++++++++++++ Tests/RunCMake/find_package-CPS/Setup.cmake | 2 + .../RunCMake/find_package-CPS/config_test.cxx | 32 ++++++++++++++++ .../find_package-CPS/cps/configdefault.cps | 21 +++++++++++ .../cps/configdefault@second.cps | 15 ++++++++ .../find_package-CPS/cps/configfirst.cps | 20 ++++++++++ .../cps/configfirst@second.cps | 15 ++++++++ .../find_package-CPS/cps/configmapped.cps | 29 +++++++++++++++ .../cps/configmatchbuildtype.cps | 37 +++++++++++++++++++ .../RunCMake/find_package-CPS/lib/libsecond.a | 0 16 files changed, 249 insertions(+), 11 deletions(-) create mode 100644 Tests/RunCMake/find_package-CPS/ConfigDefault.cmake create mode 100644 Tests/RunCMake/find_package-CPS/ConfigFirst.cmake create mode 100644 Tests/RunCMake/find_package-CPS/ConfigMapped.cmake create mode 100644 Tests/RunCMake/find_package-CPS/ConfigMatchBuildType.cmake create mode 100644 Tests/RunCMake/find_package-CPS/config_test.cxx create mode 100644 Tests/RunCMake/find_package-CPS/cps/configdefault.cps create mode 100644 Tests/RunCMake/find_package-CPS/cps/configdefault@second.cps create mode 100644 Tests/RunCMake/find_package-CPS/cps/configfirst.cps create mode 100644 Tests/RunCMake/find_package-CPS/cps/configfirst@second.cps create mode 100644 Tests/RunCMake/find_package-CPS/cps/configmapped.cps create mode 100644 Tests/RunCMake/find_package-CPS/cps/configmatchbuildtype.cps create mode 100644 Tests/RunCMake/find_package-CPS/lib/libsecond.a diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx index 37d755ef96..66e112e271 100644 --- a/Source/cmPackageInfoReader.cxx +++ b/Source/cmPackageInfoReader.cxx @@ -231,15 +231,14 @@ void AppendProperty(cmMakefile* makefile, cmTarget* target, cm::string_view property, cm::string_view configuration, std::string const& value) { - std::string fullprop; - if (configuration.empty()) { - fullprop = cmStrCat("INTERFACE_"_s, property); + std::string const fullprop = cmStrCat("INTERFACE_", property); + if (!configuration.empty()) { + std::string const genexValue = + cmStrCat("$<$:", value, '>'); + target->AppendProperty(fullprop, genexValue, makefile->GetBacktrace()); } else { - fullprop = cmStrCat("INTERFACE_"_s, property, '_', - cmSystemTools::UpperCase(configuration)); + target->AppendProperty(fullprop, value, makefile->GetBacktrace()); } - - target->AppendProperty(fullprop, value, makefile->GetBacktrace()); } template diff --git a/Tests/FindPackageCpsTest/CMakeLists.txt b/Tests/FindPackageCpsTest/CMakeLists.txt index f810425807..9d32c372fb 100644 --- a/Tests/FindPackageCpsTest/CMakeLists.txt +++ b/Tests/FindPackageCpsTest/CMakeLists.txt @@ -160,15 +160,15 @@ elseif(NOT TARGET Foo::Empty) message(SEND_ERROR "Foo::Empty missing !") else() get_property(pt_includes - TARGET Foo::PrefixTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES_DEFAULT) - if(NOT "${CMAKE_CURRENT_SOURCE_DIR}/include" PATH_EQUAL "${pt_includes}") + TARGET Foo::PrefixTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + if(NOT "${pt_includes}" STREQUAL "$<$:${CMAKE_CURRENT_SOURCE_DIR}/include>" ) message(SEND_ERROR "Foo::PrefixTest has wrong includes '${pt_includes}' !") endif() set(pt_includes) get_property(rt_includes - TARGET Foo::RelativeTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES_DEFAULT) - if(NOT "${CMAKE_CURRENT_SOURCE_DIR}/cps/../include" PATH_EQUAL "${rt_includes}") + TARGET Foo::RelativeTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + if(NOT "${rt_includes}" STREQUAL "$<$:${CMAKE_CURRENT_SOURCE_DIR}/cps/../include>") message(SEND_ERROR "Foo::RelativeTest has wrong includes '${rt_includes}' !") endif() set(rt_includes) diff --git a/Tests/RunCMake/find_package-CPS/ConfigDefault.cmake b/Tests/RunCMake/find_package-CPS/ConfigDefault.cmake new file mode 100644 index 0000000000..27fe0a0b9a --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/ConfigDefault.cmake @@ -0,0 +1,9 @@ +include(Setup.cmake) + +# Verify that CMake respects the preferred configurations as specified by a +# CPS package + +find_package(ConfigDefault REQUIRED) +add_library(config-test config_test.cxx) +target_compile_definitions(config-test PRIVATE EXPECTED_MARKER=2) +target_link_libraries(config-test ConfigDefault::target) diff --git a/Tests/RunCMake/find_package-CPS/ConfigFirst.cmake b/Tests/RunCMake/find_package-CPS/ConfigFirst.cmake new file mode 100644 index 0000000000..d55f6207d4 --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/ConfigFirst.cmake @@ -0,0 +1,9 @@ +include(Setup.cmake) + +# Verify that the first observed configuration of a component is selected when +# nothing else influences configuration selection + +find_package(ConfigFirst REQUIRED) +add_library(config-test config_test.cxx) +target_compile_definitions(config-test PRIVATE EXPECTED_MARKER=1) +target_link_libraries(config-test ConfigFirst::target) diff --git a/Tests/RunCMake/find_package-CPS/ConfigMapped.cmake b/Tests/RunCMake/find_package-CPS/ConfigMapped.cmake new file mode 100644 index 0000000000..86124dea20 --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/ConfigMapped.cmake @@ -0,0 +1,14 @@ +include(Setup.cmake) + +# Verify that MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE} can be used to select a +# configuration of a target imported via CPS + +find_package(ConfigMapped REQUIRED) +set_target_properties( + ConfigMapped::target PROPERTIES + MAP_IMPORTED_CONFIG_RELEASE test +) + +add_library(config-test STATIC config_test.cxx) +target_compile_definitions(config-test PRIVATE EXPECTED_MARKER=4) +target_link_libraries(config-test PUBLIC ConfigMapped::target) diff --git a/Tests/RunCMake/find_package-CPS/ConfigMatchBuildType.cmake b/Tests/RunCMake/find_package-CPS/ConfigMatchBuildType.cmake new file mode 100644 index 0000000000..d632f24760 --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/ConfigMatchBuildType.cmake @@ -0,0 +1,9 @@ +include(Setup.cmake) + +# Verify that CMake will select a configuration matching the current build +# type, regardless of the package's preferred configurations + +find_package(ConfigMatchBuildType REQUIRED) +add_library(config-test STATIC config_test.cxx) +target_compile_definitions(config-test PRIVATE EXPECTED_MARKER=4) +target_link_libraries(config-test ConfigMatchBuildType::target) diff --git a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake index cbc636acee..ff8aeac8ca 100644 --- a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake @@ -8,6 +8,27 @@ set(RunCMake_TEST_OPTIONS "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" ) +function(run_cmake_build test) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) + if(${ARGC} EQUAL 2) + set(_build_type ${ARGV1}) + else() + set(_build_type Release) + endif() + + if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=${_build_type}) + else() + list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=${_build_type}) + endif() + + run_cmake(${test}) + + set(RunCMake_TEST_NO_CLEAN TRUE) + run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config ${_build_type}) +endfunction() + + # Version-matching tests run_cmake(ExactVersion) run_cmake(CompatVersion) @@ -33,3 +54,9 @@ run_cmake(MissingComponentDependency) run_cmake(MissingTransitiveComponentCPS) run_cmake(MissingTransitiveComponentCMake) run_cmake(MissingTransitiveComponentDependency) + +# Configuration selection tests +run_cmake_build(ConfigDefault) +run_cmake_build(ConfigFirst) +run_cmake_build(ConfigMapped) +run_cmake_build(ConfigMatchBuildType Test) diff --git a/Tests/RunCMake/find_package-CPS/Setup.cmake b/Tests/RunCMake/find_package-CPS/Setup.cmake index df689799c1..5331ca0e1e 100644 --- a/Tests/RunCMake/find_package-CPS/Setup.cmake +++ b/Tests/RunCMake/find_package-CPS/Setup.cmake @@ -1,3 +1,5 @@ +enable_language(CXX) + # Protect tests from running inside the default install prefix. set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix") diff --git a/Tests/RunCMake/find_package-CPS/config_test.cxx b/Tests/RunCMake/find_package-CPS/config_test.cxx new file mode 100644 index 0000000000..4d354bb55f --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/config_test.cxx @@ -0,0 +1,32 @@ +#ifndef NAME +# error "NAME is not defined" +#endif +#ifndef MARKER +# error "MARKER is not defined" +#endif +#ifndef EXPECTED_MARKER +# error "EXPECTED_MARKER is not defined" +#endif + +#define STRINGIFY_IMPL(x) #x +#define STRINGIFY(x) STRINGIFY_IMPL(x) + +#if EXPECTED_MARKER > 0 +# if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) +static_assert(MARKER + 0 == EXPECTED_MARKER, + "MARKER has unexpected value " STRINGIFY(MARKER)); +static_assert(MARKER + 0 == EXPECTED_MARKER, "CONFIG is " STRINGIFY(NAME)); +# else +# if (MARKER + 0) != (EXPECTED_MARKER) +# error "MARKER has unexpected value" +# error "CONFIG mismatch for NAME" +# endif +# endif +#endif + +#ifdef _WIN32 +__declspec(dllexport) +#endif +void dummy_symbol() +{ +} diff --git a/Tests/RunCMake/find_package-CPS/cps/configdefault.cps b/Tests/RunCMake/find_package-CPS/cps/configdefault.cps new file mode 100644 index 0000000000..ef8a90a043 --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/cps/configdefault.cps @@ -0,0 +1,21 @@ +{ + "cps_version": "0.13", + "name": "ConfigDefault", + "cps_path": "@prefix@/cps", + "configurations": [ "second", "first" ], + "components": { + "target": { + "type": "interface", + "configurations": { + "first": { + "definitions": { + "*": { + "NAME": "first", + "MARKER": "1" + } + } + } + } + } + } +} diff --git a/Tests/RunCMake/find_package-CPS/cps/configdefault@second.cps b/Tests/RunCMake/find_package-CPS/cps/configdefault@second.cps new file mode 100644 index 0000000000..9959c056db --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/cps/configdefault@second.cps @@ -0,0 +1,15 @@ +{ + "cps_version": "0.13", + "name": "ConfigDefault", + "configuration": "second", + "components": { + "target": { + "definitions": { + "*": { + "NAME": "second", + "MARKER": "2" + } + } + } + } +} diff --git a/Tests/RunCMake/find_package-CPS/cps/configfirst.cps b/Tests/RunCMake/find_package-CPS/cps/configfirst.cps new file mode 100644 index 0000000000..4b71e95fe4 --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/cps/configfirst.cps @@ -0,0 +1,20 @@ +{ + "cps_version": "0.13", + "name": "ConfigFirst", + "cps_path": "@prefix@/cps", + "components": { + "target": { + "type": "interface", + "configurations": { + "first": { + "definitions": { + "*": { + "NAME": "first", + "MARKER": "1" + } + } + } + } + } + } +} diff --git a/Tests/RunCMake/find_package-CPS/cps/configfirst@second.cps b/Tests/RunCMake/find_package-CPS/cps/configfirst@second.cps new file mode 100644 index 0000000000..e5e930df2e --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/cps/configfirst@second.cps @@ -0,0 +1,15 @@ +{ + "cps_version": "0.13", + "name": "ConfigFirst", + "configuration": "second", + "components": { + "target": { + "definitions": { + "*": { + "NAME": "second", + "MARKER": "2" + } + } + } + } +} diff --git a/Tests/RunCMake/find_package-CPS/cps/configmapped.cps b/Tests/RunCMake/find_package-CPS/cps/configmapped.cps new file mode 100644 index 0000000000..d40efa39cf --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/cps/configmapped.cps @@ -0,0 +1,29 @@ +{ + "cps_version": "0.13", + "name": "ConfigMapped", + "cps_path": "@prefix@/cps", + "configurations": [ "default" ], + "components": { + "target": { + "type": "interface", + "configurations": { + "default": { + "definitions": { + "*": { + "NAME": "default", + "MARKER": "1" + } + } + }, + "test": { + "definitions": { + "*": { + "NAME": "test", + "MARKER": "4" + } + } + } + } + } + } +} diff --git a/Tests/RunCMake/find_package-CPS/cps/configmatchbuildtype.cps b/Tests/RunCMake/find_package-CPS/cps/configmatchbuildtype.cps new file mode 100644 index 0000000000..ba9e4e84da --- /dev/null +++ b/Tests/RunCMake/find_package-CPS/cps/configmatchbuildtype.cps @@ -0,0 +1,37 @@ +{ + "cps_version": "0.13", + "name": "ConfigMatchBuildType", + "cps_path": "@prefix@/cps", + "configurations": [ "release", "debug"], + "components": { + "target": { + "type": "interface", + "configurations": { + "debug": { + "definitions": { + "*": { + "NAME": "debug", + "MARKER": "1" + } + } + }, + "release": { + "definitions": { + "*": { + "NAME": "release", + "MARKER": "2" + } + } + }, + "test": { + "definitions": { + "*": { + "NAME": "test", + "MARKER": "4" + } + } + } + } + } + } +} diff --git a/Tests/RunCMake/find_package-CPS/lib/libsecond.a b/Tests/RunCMake/find_package-CPS/lib/libsecond.a new file mode 100644 index 0000000000..e69de29bb2