mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-10-07 04:02:23 +03:00
While evaluating best practices related to CPS configuration use, a question was raised as to what configuration mapping CMake uses to choose the configuration of a target linked by another imported target for which a non-standard configuration was chosen; namely, does CMake use the `MAP_IMPORTED_CONFIG_<CONFIG>` for the configuration associated with the most ancestral target / the project's build type, or for the selected configuration of the direct consumer of the target? It turns out the answer is "the former", and that this is actually the more user-beneficial choice, as it allows users to craft configuration maps that easily allow multi-axis configuration selection on correctly crafter hierarchies, which are something CPS has "recommended" almost since its inception (but CMake cannot presently generate). This has three effects. First, it means that CPS suggesting such hierarchies as a way to implement multiple configuration axes is not actually as insane as it would be otherwise. Second, it means that consumers can specify mappings for transitively included targets without needing to know or care about what configurations of the intervening targets exist. Third, it means that the current behavior is desirable, and having something which verifies that behavior is useful. Thus, this adds a test to do exactly that. There are no actual behavior changes here; the test only verifies the already existing behavior.
62 lines
2.6 KiB
CMake
62 lines
2.6 KiB
CMake
include(RunCMake)
|
|
|
|
set(RunCMake_TEST_OPTIONS
|
|
-Wno-dev
|
|
"-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
|
|
)
|
|
|
|
function(build_project test)
|
|
set(RunCMake_TEST_NO_CLEAN FALSE)
|
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
|
|
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
|
list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
|
|
endif()
|
|
|
|
run_cmake(${test})
|
|
|
|
set(RunCMake_TEST_NO_CLEAN TRUE)
|
|
run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release)
|
|
endfunction()
|
|
|
|
#[[
|
|
These tests are not testing CPS as such, but rather are testing the way that
|
|
CMake maps configurations; specifically, which MAP_IMPORTED_CONFIG_<CONFIG> is
|
|
considered when selecting a configuration of a target required by another
|
|
target for which a non-standard configuration has been selected.
|
|
|
|
It happens that CMake's behavior is to always use the configuration of the
|
|
project being built, and not the selected configuration of the consumer of the
|
|
target for which configuration selection is occurring. This turns out to be
|
|
advantageous, as it makes it relatively simple to use chains of interface
|
|
targets to select along multiple configuration axes, since it is relatively
|
|
simple for projects to set CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> to a list of
|
|
preferred values along each axis and be sure the same list will be used for
|
|
each level of selection.
|
|
|
|
This test/example uses the following hierarchy:
|
|
target "animal", configurations "cat", "dog"
|
|
targets "cat", "dog", configurations "tame", "wild"
|
|
|
|
The consuming project sets CMAKE_MAP_IMPORTED_CONFIG_<CONFIG> to the list of
|
|
desired values on each of the two axes, e.g. "CAT;TAME". This causes CMake to
|
|
select the "CAT" configuration of the "animal" target, which links "cat",
|
|
then, because CMake is still using MAP_IMPORTED_CONFIG_${CMAKE_BUILD_TYPE},
|
|
to select the "TAME" configuration of the "cat" target.
|
|
|
|
A more practical example is described by CPS, at
|
|
https://cps-org.github.io/cps/recommendations.html.
|
|
|
|
The main reason this is a "CPS" test is because CPS makes it possible to
|
|
provide targets which implement multiple configuration axes in a way that is
|
|
surprisingly usable by CMake consumers. However, CMake itself has no way of
|
|
generating such exports as of when this test is being added (CMake 4.3). Thus,
|
|
it is testing something which is suggested by CPS, but is unlikely to be
|
|
encountered in a CMake-created package. (In principle, however, a hand-written
|
|
CMake-script package description could produce equivalent imported targets.)
|
|
#]]
|
|
|
|
build_project(TestTameCat)
|
|
build_project(TestWildCat)
|
|
build_project(TestTameDog)
|
|
build_project(TestWildDog)
|