Merge topic 'tests-property_init-lint'

eba57196e7 Tests/RunCMake/property_init: Add lint/coverage case
29315ad49e Tests/RunCMake/property_init: Fix per-config property tests
825a52a64e Tests/RunCMake/property_init: Fix ENABLE_EXPORTS target type lists
a4d3c8b625 Tests/RunCMake/property_init: Remove duplication in PIC case
19c9125289 Tests/RunCMake/property_init: Add missing properties

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Robert Maynard <robertjmaynard@gmail.com>
Merge-request: !12723
This commit is contained in:
Brad King authored and Kitware Robot committed 2026-10-28 09:28:55 -04:00
commit b3fbc49372
15 files changed
+268 -28

No files matched your search

+1 -1
View File
@@ -897,7 +897,7 @@ add_RunCMake_test(option)
add_RunCMake_test(PrintHelpers)
add_RunCMake_test(project -DCMake_TEST_RESOURCES=${CMake_TEST_RESOURCES})
add_RunCMake_test(project_injected)
add_RunCMake_test(property_init)
add_RunCMake_test(property_init -DCMake_SOURCE_DIR=${CMake_SOURCE_DIR})
add_RunCMake_test(DependencyProviders)
add_RunCMake_test(return)
add_RunCMake_test(SarifOutput)
@@ -25,6 +25,7 @@ set(properties
"OSX_ARCHITECTURES" "arm64" "<SAME>"
### Windows
"MSVC_DEBUG_INFORMATION_FORMAT" "Embedded" "<SAME>"
"MSVC_RUNTIME_CHECKS" "StackFrameErrorCheck" "<SAME>"
"MSVC_RUNTIME_LIBRARY" "MultiThreaded" "<SAME>"
"VS_JUST_MY_CODE_DEBUGGING" "ON" "<SAME>"
### OpenWatcom
@@ -49,6 +50,12 @@ set(properties
### Swift
"Swift_LANGUAGE_VERSION" "2.3" "<SAME>"
"Swift_MODULE_DIRECTORY" "${dir}" "<SAME>"
"Swift_COMPILATION_MODE" "incremental" "<SAME>"
"Swift_SEPARATE_MODULE_EMISSION" "ON" "<SAME>"
### Rust
"Rust_COMPILER_LAUNCHER" "ccache" "<SAME>"
"Rust_EDITION" "2021" "<SAME>"
"Rust_MAIN_CRATE_ROOT" "main.rs" "<SAME>"
### SYCL
"SYCL_COMPILER_LAUNCHER" "ccache" "<SAME>"
"SYCL_CXX_STANDARD" "17" "<SAME>"
@@ -57,9 +64,11 @@ set(properties
"SYCL_VISIBILITY_PRESET" "hidden" "<SAME>"
"SYCL_SEPARABLE_COMPILATION" "ON" "<SAME>"
"SYCL_EXTENSION_MODE" "REPLACE" "<SAME>"
"SYCL_DEVICE_TARGETS" "spir64" "<SAME>"
### moc
"AUTOMOC" "OFF" "<SAME>"
"AUTOMOC_COMPILER_PREDEFINES" "OFF" "<SAME>"
"AUTOMOC_INCLUDE_DIRECTORIES" "${dir}" "<SAME>"
"AUTOMOC_MACRO_NAMES" "MOC_CLASS" "<SAME>"
"AUTOMOC_MOC_OPTIONS" "-v" "<SAME>"
"AUTOMOC_PATH_PREFIX" "moc_" "<SAME>"
@@ -75,6 +84,8 @@ set(properties
"AUTORCC_EXECUTABLE" "autorcc" "<SAME>"
# Linking properties
"LINKER_TYPE" "DEFAULT" "<SAME>"
"LINK_WARNING_AS_ERROR" "OFF" "<SAME>"
"LINK_SEARCH_START_STATIC" "-Bstatic" "<SAME>"
"LINK_SEARCH_END_STATIC" "-Bdynamic" "<SAME>"
## Dependent library lookup
@@ -112,14 +123,18 @@ set(properties
### C++
"CXX_LINKER_LAUNCHER" "ccache" "<SAME>"
### CUDA
"CUDA_LINKER_LAUNCHER" "ccache" "<SAME>"
"CUDA_RESOLVE_DEVICE_SYMBOLS" "ON" "<SAME>"
"CUDA_RUNTIME_LIBRARY" "Static" "<SAME>"
### HIP
"HIP_LINKER_LAUNCHER" "ccache" "<SAME>"
"HIP_RUNTIME_LIBRARY" "SHARED" "<SAME>"
### Objective C
"OBJC_LINKER_LAUNCHER" "ccache" "<SAME>"
### Objective C++
"OBJCXX_LINKER_LAUNCHER" "ccache" "<SAME>"
### Fortran
"Fortran_LINKER_LAUNCHER" "ccache" "<SAME>"
### SYCL
"SYCL_LINKER_LAUNCHER" "ccache" "<SAME>"
@@ -133,6 +148,7 @@ set(properties
"C_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
"C_CPPLINT" "cpplint" "<SAME>"
"C_CPPCHECK" "cppcheck" "<SAME>"
"C_ICSTAT" "icstat" "<SAME>"
"C_INCLUDE_WHAT_YOU_USE" "iwyu" "<SAME>"
"C_PVS_STUDIO" "pvs-studio-analyzer" "<SAME>"
## C++
@@ -140,6 +156,7 @@ set(properties
"CXX_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
"CXX_CPPLINT" "cpplint" "<SAME>"
"CXX_CPPCHECK" "cppcheck" "<SAME>"
"CXX_ICSTAT" "icstat" "<SAME>"
"CXX_INCLUDE_WHAT_YOU_USE" "iwyu" "<SAME>"
"CXX_PVS_STUDIO" "pvs-studio-analyzer" "<SAME>"
## Objective C
@@ -157,12 +174,15 @@ set(properties
"UNITY_BUILD_UNIQUE_ID" "unity" "<SAME>"
"UNITY_BUILD_BATCH_SIZE" "10" "<SAME>"
"UNITY_BUILD_MODE" "GROUP" "<SAME>"
"UNITY_BUILD_RELOCATABLE" "ON" "<SAME>"
"OPTIMIZE_DEPENDENCIES" "ON" "<SAME>"
## Android
"ANDROID_ANT_ADDITIONAL_OPTIONS" "-v" "<SAME>"
"ANDROID_PROCESS_MAX" "2" "<SAME>"
"ANDROID_SKIP_ANT_STEP" "ON" "<SAME>"
## Autogen
"AUTOGEN_BETTER_GRAPH_MULTI_CONFIG" "ON" "<SAME>"
"AUTOGEN_COMMAND_LINE_LENGTH_MAX" "32000" "<SAME>"
"AUTOGEN_ORIGIN_DEPENDS" "OFF" "<SAME>"
"AUTOGEN_PARALLEL" "ON" "<SAME>"
"AUTOGEN_USE_SYSTEM_INCLUDE" "ON" "<SAME>"
+183
View File
@@ -0,0 +1,183 @@
# Check that every property initialized from `StaticTargetProperties` in
# `Source/cmTarget.cxx` is tested by the case file matching its
# `InitCondition`, and that every property tested here is still initialized.
set(source_file "${CMake_SOURCE_DIR}/Source/cmTarget.cxx")
if (NOT EXISTS "${source_file}")
message(FATAL_ERROR
"Source file not found: '${source_file}'")
endif ()
# Map each `InitCondition` to the case file testing it.
set(case_for_Always "Always")
set(case_for_CanCompileSources "CompileSources")
set(case_for_NeedsXcodeAndCanCompileSources "CompileSources")
set(case_for_NormalTarget "NormalTarget")
set(case_for_NonImportedTarget "NonImportedTarget")
set(case_for_NormalNonImportedTarget "NonImportedNormalTarget")
set(case_for_TargetWithArtifact "TargetsWithArtifact")
set(case_for_NonExecutableWithArtifact "LibraryArtifact")
set(case_for_LinkableLibraryTarget "Linkable")
set(case_for_ExecutableTarget "Executable")
set(case_for_SharedLibraryTarget "SharedLibrary")
set(case_for_TargetWithSymbolExports "TargetsWithExports")
set(case_for_TargetWithCommands "TargetsWithCommands")
# Properties tested by a case other than the one for their `InitCondition`.
set(case_override_POSITION_INDEPENDENT_CODE "PICTargets")
# Properties in the table which are not tested.
set(untested
# property reason
"XCODE_GENERATE_SCHEME" "NeedsXcode: no Xcode-only, all-target-type case"
)
# Properties tested which are not initialized from the table.
set(not_in_table
# property reason
"notset" "Never initialized, checks the harness itself"
"SYSTEM" "Initialized separately for non-normal targets"
)
# Extract the property names from a "property reason" table.
function (prepare_properties_table table output)
set(_properties)
set(is_property 1)
foreach (item IN LISTS "${table}")
if (is_property)
list(APPEND _properties "${item}")
set(is_property 0)
else ()
set(is_property 1)
endif ()
endforeach ()
set("${output}" "${_properties}" PARENT_SCOPE)
endfunction ()
# Parse the source table.
file(READ "${source_file}" source)
string(REPLACE ";" "" source "${source}")
string(REPLACE "\\" "" source "${source}")
string(FIND "${source}" "#define COMMON_LANGUAGE_PROPERTIES(lang)" macro_begin)
string(FIND "${source}" "TargetProperty const StaticTargetProperties[] = {" table_begin)
if (macro_begin EQUAL -1 OR table_begin EQUAL -1)
message(FATAL_ERROR
"Failed to find `StaticTargetProperties` in '${source_file}'")
endif ()
math(EXPR macro_length "${table_begin} - ${macro_begin}")
string(SUBSTRING "${source}" "${macro_begin}" "${macro_length}" macro_text)
string(SUBSTRING "${source}" "${table_begin}" -1 table_text)
string(FIND "${table_text}" "\n};" table_end)
string(SUBSTRING "${table_text}" 0 "${table_end}" table_text)
set(language_suffixes)
string(REPLACE "\n" ";" macro_lines "${macro_text}")
foreach (line IN LISTS macro_lines)
if (line MATCHES "\\{ #lang \"([A-Za-z_]+)\"_s, IC::([A-Za-z]+)")
list(APPEND language_suffixes "${CMAKE_MATCH_1}")
set("language_ic_${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}")
endif ()
endforeach ()
set(source_properties)
string(REPLACE "\n" ";" table_lines "${table_text}")
foreach (line IN LISTS table_lines)
if (line MATCHES "^ *\\{ \"([A-Za-z_]+)\"_s(, \"[^\"]*\"_s)?(, IC::([A-Za-z]+))?")
set(property "${CMAKE_MATCH_1}")
set(ic "${CMAKE_MATCH_4}")
if (ic STREQUAL "")
set(ic "Always")
endif ()
list(APPEND source_properties "${property}")
set("source_ic_${property}" "${ic}")
elseif (line MATCHES "^ *COMMON_LANGUAGE_PROPERTIES\\(([A-Za-z]+)\\)")
set(lang "${CMAKE_MATCH_1}")
foreach (suffix IN LISTS language_suffixes)
list(APPEND source_properties "${lang}${suffix}")
set("source_ic_${lang}${suffix}" "${language_ic_${suffix}}")
endforeach ()
endif ()
endforeach ()
if (NOT source_properties)
message(FATAL_ERROR
"Failed to parse any properties from '${source_file}'")
endif ()
# Parse the test tables. Rows look like `"PROPERTY" "expected" "alias"`.
file(GLOB case_files "${CMAKE_CURRENT_LIST_DIR}/*.cmake")
list(REMOVE_ITEM case_files
"${CMAKE_CURRENT_LIST_DIR}/Coverage.cmake"
"${CMAKE_CURRENT_LIST_DIR}/RunCMakeTest.cmake"
"${CMAKE_CURRENT_LIST_DIR}/util.cmake"
)
set(tested_properties)
foreach (case_file IN LISTS case_files)
get_filename_component(case "${case_file}" NAME_WE)
file(STRINGS "${case_file}" lines)
set(language_templates)
set(languages)
foreach (line IN LISTS lines)
if (line MATCHES "^ *\"([A-Za-z_]+)\" +\"")
list(APPEND tested_properties "${CMAKE_MATCH_1}")
list(APPEND "tested_cases_${CMAKE_MATCH_1}" "${case}")
elseif (line MATCHES "^ *\"\\\${lang}([A-Za-z_]+)\" +\"")
list(APPEND language_templates "${CMAKE_MATCH_1}")
elseif (line MATCHES "^add_language_properties\\(([A-Za-z]+) ")
list(APPEND languages "${CMAKE_MATCH_1}")
endif ()
endforeach ()
foreach (lang IN LISTS languages)
foreach (suffix IN LISTS language_templates)
list(APPEND tested_properties "${lang}${suffix}")
list(APPEND "tested_cases_${lang}${suffix}" "${case}")
endforeach ()
endforeach ()
endforeach ()
list(REMOVE_DUPLICATES tested_properties)
# Every source property must be tested in its case (or be listed as untested).
prepare_properties_table(untested untested_properties)
foreach (property IN LISTS source_properties)
set(ic "${source_ic_${property}}")
if (DEFINED "case_override_${property}")
set(case "${case_override_${property}}")
elseif (DEFINED "case_for_${ic}")
set(case "${case_for_${ic}}")
else ()
set(case "")
endif ()
if (property IN_LIST untested_properties)
if (DEFINED "tested_cases_${property}")
message(SEND_ERROR
"Property '${property}' is listed as untested in Coverage.cmake, but "
"is tested in: ${tested_cases_${property}}")
endif ()
elseif (case STREQUAL "")
message(SEND_ERROR
"Property '${property}' uses `IC::${ic}`, which has no case mapped in "
"Coverage.cmake")
elseif (NOT DEFINED "tested_cases_${property}")
message(SEND_ERROR
"Property '${property}' (`IC::${ic}`) is initialized in cmTarget.cxx, "
"but is not tested in ${case}.cmake")
elseif (NOT case IN_LIST "tested_cases_${property}")
message(SEND_ERROR
"Property '${property}' (`IC::${ic}`) should be tested in "
"${case}.cmake, but is tested in: ${tested_cases_${property}}")
endif ()
endforeach ()
# Every tested property must still be initialized from the table.
prepare_properties_table(not_in_table not_in_table_properties)
foreach (property IN LISTS tested_properties)
if (NOT property IN_LIST source_properties AND
NOT property IN_LIST not_in_table_properties)
message(SEND_ERROR
"Property '${property}' is tested in ${tested_cases_${property}}, but "
"is not initialized from `StaticTargetProperties` in cmTarget.cxx")
endif ()
endforeach ()
@@ -2,6 +2,9 @@ set(dir "${CMAKE_CURRENT_BINARY_DIR}")
set(properties
# property expected alias
# Debugger properties
"DEBUGGER_WORKING_DIRECTORY" "${dir}" "<SAME>"
# Compilation properties
## Platforms
### Windows
@@ -1,10 +1,10 @@
per_config(properties
# property expected alias
# Linking properties
"_POSTFIX" "test" "<UNSET>"
"_POSTFIX" "test" "<SAME>"
)
prepare_target_types(library_with_artifact
MODULE SHARED STATIC
IMPORTED_MODULE IMPORTED_SHARED IMPORTED_STATIC)
MODULE OBJECT SHARED STATIC
IMPORTED_MODULE IMPORTED_OBJECT IMPORTED_SHARED IMPORTED_STATIC)
run_property_tests(library_with_artifact properties)
+3 -3
View File
@@ -3,10 +3,10 @@ per_config(properties
# Linking properties
## Platforms
### macOS
"FRAMEWORK_MULTI_CONFIG_POSTFIX_" ".fw" "<UNSET>"
"FRAMEWORK_MULTI_CONFIG_POSTFIX_" ".fw" "<SAME>"
)
prepare_target_types(linkable
EXECUTABLE SHARED STATIC
IMPORTED_EXECUTABLE IMPORTED_SHARED IMPORTED_STATIC)
SHARED STATIC
IMPORTED_SHARED IMPORTED_STATIC)
run_property_tests(linkable properties)
@@ -1,7 +1,8 @@
set(properties
# property expected alias
# property expected alias
# Linking properties
"LINK_LIBRARIES_ONLY_TARGETS" "OFF" "<SAME>"
"LINK_LIBRARIES_ONLY_TARGETS" "OFF" "<SAME>"
"LINK_LIBRARIES_STRATEGY" "REORDER_MINIMALLY" "<SAME>"
)
prepare_target_types(normal_non_imported
@@ -1,6 +1,9 @@
set(properties
# property expected alias
# Compilation properties
## Platforms
### Windows
"VS_USE_DEBUG_LIBRARIES" "OFF" "<SAME>"
## Language
### CSharp
"DOTNET_SDK" "Microsoft.NET.Sdk" "<SAME>"
@@ -1,7 +1,12 @@
per_config(properties
# property expected alias
# Usage requirement properties
"MAP_IMPORTED_CONFIG_" "Release" "<UNSET>"
"MAP_IMPORTED_CONFIG_" "Release" "<SAME>"
)
list(APPEND properties
# property expected alias
# Usage requirement properties
"EXPORT_FIND_PACKAGE_NAME" "pkg" "<SAME>"
)
prepare_target_types(normal
@@ -9,13 +9,8 @@ prepare_target_types(pic_targets
IMPORTED_MODULE IMPORTED_SHARED)
run_property_tests(pic_targets properties)
set(APPEND properties_with_defaults
# property expected alias
"POSITION_INDEPENDENT_CODE" "True" "<SAME>"
)
prepare_target_types(pic_default_targets
MODULE SHARED
IMPORTED_MODULE IMPORTED_SHARED)
set(with_defaults 1)
run_property_tests(pic_default_targets properties_with_defaults)
run_property_tests(pic_default_targets properties)
@@ -1,5 +1,10 @@
include(RunCMake)
# Per-config properties are only initialized for known configurations.
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
endif ()
run_cmake(Always)
run_cmake(CompileSources)
run_cmake(Executable)
@@ -14,3 +19,5 @@ run_cmake(SharedLibrary)
run_cmake(TargetsWithArtifact)
run_cmake(TargetsWithCommands)
run_cmake(TargetsWithExports)
run_cmake_script(Coverage -DCMake_SOURCE_DIR=${CMake_SOURCE_DIR})
@@ -10,3 +10,17 @@ prepare_target_types(shared_library
SHARED
IMPORTED_SHARED)
run_property_tests(shared_library properties)
set(properties
# property expected alias
# Linking properties
## Platforms
### AIX
# Imported targets must set `AIX_SHARED_LIBRARY_ARCHIVE` explicitly.
"AIX_SHARED_LIBRARY_ARCHIVE" "OFF" "<SAME>"
)
prepare_target_types(non_imported_shared_library
SHARED)
set(iteration "-AIX_SHARED_LIBRARY_ARCHIVE")
run_property_tests(non_imported_shared_library properties)
@@ -3,17 +3,17 @@ set(dir "${CMAKE_CURRENT_BINARY_DIR}")
per_config(properties
# property expected alias
# Compilation properties
"INTERPROCEDURAL_OPTIMIZATION_" "OFF" "<UNSET>"
"INTERPROCEDURAL_OPTIMIZATION_" "OFF" "<SAME>"
# Output location properties
"ARCHIVE_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
"COMPILE_PDB_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
"LIBRARY_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
"PDB_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
"RUNTIME_OUTPUT_DIRECTORY_" "${dir}" "<UNSET>"
"ARCHIVE_OUTPUT_DIRECTORY_" "${dir}" "<SAME>"
"COMPILE_PDB_OUTPUT_DIRECTORY_" "${dir}" "<SAME>"
"LIBRARY_OUTPUT_DIRECTORY_" "${dir}" "<SAME>"
"PDB_OUTPUT_DIRECTORY_" "${dir}" "<SAME>"
"RUNTIME_OUTPUT_DIRECTORY_" "${dir}" "<SAME>"
)
prepare_target_types(with_artifact
EXECUTABLE MODULE SHARED STATIC
IMPORTED_EXECUTABLE IMPORTED_MODULE IMPORTED_SHARED IMPORTED_STATIC)
EXECUTABLE MODULE OBJECT SHARED STATIC
IMPORTED_EXECUTABLE IMPORTED_MODULE IMPORTED_OBJECT IMPORTED_SHARED IMPORTED_STATIC)
run_property_tests(with_artifact properties)
@@ -20,9 +20,12 @@ set(properties
"ENABLE_EXPORTS" "OFF" "<SAME>"
)
prepare_target_types(executable
prepare_target_types(executable_target
EXECUTABLE
IMPORTED_EXECUTABLE)
prepare_target_types(shared_library_target
SHARED
IMPORTED_SHARED)
set(iteration "-ENABLE_EXPORTS")
run_property_tests(executable_target properties)
+9 -3
View File
@@ -24,7 +24,8 @@ function (prepare_target_types name)
endfunction ()
function (per_config variable)
prepare_properties("${property_table}" properties expected_values expected_alias)
set(property_table "${ARGN}")
prepare_properties(property_table expected_properties expected_values expected_alias)
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (is_multi_config)
@@ -34,6 +35,11 @@ function (per_config variable)
set(configs "${CMAKE_BUILD_TYPE}")
endif ()
endif ()
if (NOT configs)
message(FATAL_ERROR
"No configurations available to test per-config properties")
endif ()
string(TOUPPER "${configs}" configs)
foreach (property expected alias IN ZIP_LISTS expected_properties expected_values expected_alias)
if (property MATCHES "^_")
@@ -47,10 +53,10 @@ function (per_config variable)
foreach (config IN LISTS configs)
if (prepend)
list(APPEND "${variable}"
"${config}_${property}" "${value}/${config}" "${alias}")
"${config}${property}" "${expected}-${config}" "${alias}")
else ()
list(APPEND "${variable}"
"${property}_${config}" "${value}/${config}" "${alias}")
"${property}${config}" "${expected}-${config}" "${alias}")
endif ()
endforeach ()
endforeach ()