CMP0155: ignore scanning for sources if no scanner is available

This allows for a more graceful transition for projects using C++20
without scanner support (e.g., Clang 15 or GCC 13). While newer
compilers will (needlessly) scan, it allows C++20-using projects to use
older compilers without having to set `CMAKE_CXX_SCAN_FOR_MODULES` to
support newer CMake minimum versions.

Fixes: #25357
This commit is contained in:
Ben Boeckel
2023-10-27 22:43:37 -04:00
committed by Brad King
parent e3747a2d4b
commit 889aa0354a
10 changed files with 33 additions and 23 deletions

View File

@@ -27,7 +27,8 @@ following queries. The first query that provides a yes/no answer is used.
- If the :prop_tgt:`CXX_SCAN_FOR_MODULES` target property is set, its value
will be used. Set the :variable:`CMAKE_CXX_SCAN_FOR_MODULES` variable
to initialize this property on all targets as they are created.
- Otherwise, the source file will be scanned. See policy :policy:`CMP0155`.
- Otherwise, the source file will be scanned if the compiler and generator
support scanning. See policy :policy:`CMP0155`.
Compiler Support
================

View File

@@ -57,7 +57,7 @@ Policies Introduced by CMake 3.28
.. toctree::
:maxdepth: 1
CMP0155: C++ sources in targets with at least C++20 are scanned for imports. </policy/CMP0155>
CMP0155: C++ sources in targets with at least C++20 are scanned for imports when supported. </policy/CMP0155>
CMP0154: Generated files are private by default in targets using file sets. </policy/CMP0154>
CMP0153: The exec_program command should not be called. </policy/CMP0153>
CMP0152: file(REAL_PATH) resolves symlinks before collapsing ../ components. </policy/CMP0152>

View File

@@ -3,7 +3,8 @@ CMP0155
.. versionadded:: 3.28
C++ sources in targets with at least C++20 are scanned for imports.
C++ sources in targets with at least C++20 are scanned for imports
when supported.
CMake 3.27 and below assume that C++ sources do not ``import`` modules.
CMake 3.28 and above prefer to assume that C++ sources in targets using C++20
@@ -16,7 +17,8 @@ support.
The ``OLD`` behavior for this policy is to assume that C++ 20 and newer
sources do not import modules. The ``NEW`` behavior for this policy is to
assume that C++ 20 and newer files may import modules, and need to be scanned.
assume that C++ 20 and newer files may import modules if the compiler
understands how to scan for their dependencies, and need to be scanned.
This policy was introduced in CMake version 3.28. Use the
:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.

View File

@@ -9292,14 +9292,19 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
return true;
}
bool haveRule = false;
switch (this->HaveCxxModuleSupport(config)) {
case Cxx20SupportLevel::MissingCxx:
case Cxx20SupportLevel::NoCxx20:
return false;
case Cxx20SupportLevel::MissingRule:
break;
case Cxx20SupportLevel::Supported:
haveRule = true;
break;
}
bool haveGeneratorSupport =
this->GetGlobalGenerator()->CheckCxxModuleSupport();
auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
if (sfProp.IsSet()) {
return sfProp.IsOn();
@@ -9319,8 +9324,9 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
// The NEW behavior is to scan the source.
policyAnswer = true;
// The NEW behavior is to scan the source if the compiler supports
// scanning and the generator supports it.
policyAnswer = haveRule && haveGeneratorSupport;
break;
}
return policyAnswer;

View File

@@ -470,10 +470,10 @@ class cmMakefile;
POLICY, CMP0154, \
"Generated files are private by default in targets using file sets.", 3, \
28, 0, cmPolicies::WARN) \
SELECT( \
POLICY, CMP0155, \
"C++ sources in targets with at least C++20 are scanned for imports", 3, \
28, 0, cmPolicies::WARN)
SELECT(POLICY, CMP0155, \
"C++ sources in targets with at least C++20 are scanned for " \
"imports when supported.", \
3, 28, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@@ -1,10 +0,0 @@
(CMake Error in CMakeLists.txt:
The target named "cmp0155-new" has C\+\+ sources that may use modules, but
the compiler does not provide a way to discover the import graph
dependencies\. See the cmake-cxxmodules\(7\) manual and the
CMAKE_CXX_SCAN_FOR_MODULES variable\.
|CMake Error in CMakeLists.txt:
The target named "cmp0155-new" has C\+\+ sources that may use modules, but
modules are not supported by this generator\. See the cmake-cxxmodules\(7\)
manual and the CMAKE_CXX_SCAN_FOR_MODULES variable\.
)

View File

@@ -0,0 +1,11 @@
enable_language(CXX)
set(CMAKE_CXX_SCANDEP_SOURCE "echo")
cmake_policy(SET CMP0155 NEW)
add_executable(cmp0155-new-with-rule
sources/module-use.cxx)
set_target_properties(cmp0155-new-with-rule
PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON)

View File

@@ -3,8 +3,8 @@ unset(CMAKE_CXX_SCANDEP_SOURCE)
cmake_policy(SET CMP0155 NEW)
add_executable(cmp0155-new
sources/module-use.cxx)
add_library(cmp0155-new
sources/cxx-anchor.cxx)
set_target_properties(cmp0155-new
PROPERTIES
CXX_STANDARD 20

View File

@@ -23,6 +23,7 @@ if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
run_cmake(NoScanningVariable)
run_cmake(CMP0155-OLD)
run_cmake(CMP0155-NEW)
run_cmake(CMP0155-NEW-with-rule)
endif ()
if (RunCMake_GENERATOR MATCHES "Ninja")