summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-cxxmodules.7.rst17
-rw-r--r--Source/cmGeneratorTarget.cxx122
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx8
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx8
-rw-r--r--Source/cmMakefileTargetGenerator.cxx8
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx9
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX-stderr.txt13
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20-stderr.txt14
-rw-r--r--Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt8
-rw-r--r--Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-result.txt1
-rw-r--r--Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/NoScanningSourceFileProperty.cmake13
-rw-r--r--Tests/RunCMake/CXXModules/NoScanningTargetProperty-result.txt1
-rw-r--r--Tests/RunCMake/CXXModules/NoScanningTargetProperty-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/NoScanningTargetProperty.cmake10
-rw-r--r--Tests/RunCMake/CXXModules/RunCMakeTest.cmake3
16 files changed, 166 insertions, 87 deletions
diff --git a/Help/manual/cmake-cxxmodules.7.rst b/Help/manual/cmake-cxxmodules.7.rst
index 91acae1..a082f58 100644
--- a/Help/manual/cmake-cxxmodules.7.rst
+++ b/Help/manual/cmake-cxxmodules.7.rst
@@ -12,6 +12,23 @@ to scan source files for module dependencies during the build, collates
scanning results to infer ordering constraints, and tells the build tool
how to dynamically update the build graph.
+Scanning Control
+================
+
+Whether or not sources get scanned for C++ module usage is dependent on the
+following queries. The first query that provides a yes/no answer is used.
+
+- If the source file belongs to a file set of type ``CXX_MODULES``, it will
+ be scanned.
+- If the target does not use at least C++ 20, it will not be scanned.
+- If the source file is not the language ``CXX``, it will not be scanned.
+- If the :prop_sf:`CXX_SCAN_FOR_MODULES` source file property is set, its
+ value will be 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 will be scanned.
+
Compiler Support
================
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index bbb47e4..93946aa 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -9115,39 +9115,83 @@ cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
{
+ bool haveScannableSources = false;
+
// Check for `CXX_MODULE*` file sets and a lack of support.
if (this->HaveCxx20ModuleSources()) {
- switch (this->HaveCxxModuleSupport(config)) {
- case cmGeneratorTarget::Cxx20SupportLevel::MissingCxx:
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("The target named \"", this->GetName(),
- "\" has C++ sources that export modules but the \"CXX\" "
- "language has not been enabled"));
- break;
- case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20: {
- cmStandardLevelResolver standardResolver(this->Makefile);
- auto effStandard =
- standardResolver.GetEffectiveStandard(this, "CXX", config);
- if (effStandard.empty()) {
- effStandard = "; no C++ standard found";
- } else {
- effStandard = cmStrCat("; found \"cxx_std_", effStandard, '"');
- }
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat(
- "The target named \"", this->GetName(),
- "\" has C++ sources that export modules but does not include "
- "\"cxx_std_20\" (or newer) among its `target_compile_features`",
- effStandard));
- } break;
- case cmGeneratorTarget::Cxx20SupportLevel::MissingRule:
- case cmGeneratorTarget::Cxx20SupportLevel::Supported:
- // All is well.
- break;
+ haveScannableSources = true;
+ }
+
+ if (!haveScannableSources) {
+ // Check to see if there are regular sources that have requested scanning.
+ auto sources = cmGeneratorTarget::GetSourceFiles(config);
+ for (auto const& source : sources) {
+ auto const* sf = source.Value;
+ auto const& lang = sf->GetLanguage();
+ if (lang != "CXX"_s) {
+ continue;
+ }
+ // Ignore sources which do not need dyndep.
+ if (this->NeedDyndepForSource(lang, config, sf)) {
+ haveScannableSources = true;
+ }
}
}
+
+ // If there isn't anything scannable, ignore it.
+ if (!haveScannableSources) {
+ return;
+ }
+
+ // If the generator doesn't support modules at all, error that we have
+ // sources that require the support.
+ if (!this->GetGlobalGenerator()->CheckCxxModuleSupport()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "The target named \"", this->GetName(),
+ "\" contains C++ "
+ "sources that use modules which is not supported by the generator"));
+ return;
+ }
+
+ switch (this->HaveCxxModuleSupport(config)) {
+ case cmGeneratorTarget::Cxx20SupportLevel::MissingCxx:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The target named \"", this->GetName(),
+ "\" has C++ sources that use modules but the \"CXX\" "
+ "language has not been enabled"));
+ break;
+ case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20: {
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ auto effStandard =
+ standardResolver.GetEffectiveStandard(this, "CXX", config);
+ if (effStandard.empty()) {
+ effStandard = "; no C++ standard found";
+ } else {
+ effStandard = cmStrCat("; found \"cxx_std_", effStandard, '"');
+ }
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "The target named \"", this->GetName(),
+ "\" has C++ sources that use modules but does not include "
+ "\"cxx_std_20\" (or newer) among its `target_compile_features`",
+ effStandard));
+ } break;
+ case cmGeneratorTarget::Cxx20SupportLevel::MissingRule: {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The target named \"", this->GetName(),
+ "\" has C++ sources that use modules but the compiler does "
+ "not provide a way to discover the import graph "
+ "dependencies"));
+ } break;
+ case cmGeneratorTarget::Cxx20SupportLevel::Supported:
+ // All is well.
+ break;
+ }
}
bool cmGeneratorTarget::NeedCxxModuleSupport(std::string const& lang,
@@ -9185,14 +9229,30 @@ bool cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
std::string const& config,
cmSourceFile const* sf) const
{
- bool const needDyndep = this->NeedDyndep(lang, config);
- if (!needDyndep) {
+ // Fortran always needs to be scanned.
+ if (lang == "Fortran"_s) {
+ return true;
+ }
+ // Only C++ code needs scanned otherwise.
+ if (lang != "CXX"_s) {
return false;
}
+
+ // Any file in `CXX_MODULES` file sets need scanned (it being `CXX` is
+ // enforced elsewhere).
auto const* fs = this->GetFileSetForSource(config, sf);
if (fs && fs->GetType() == "CXX_MODULES"_s) {
return true;
}
+
+ switch (this->HaveCxxModuleSupport(config)) {
+ case Cxx20SupportLevel::MissingCxx:
+ case Cxx20SupportLevel::NoCxx20:
+ return false;
+ case Cxx20SupportLevel::MissingRule:
+ case Cxx20SupportLevel::Supported:
+ break;
+ }
auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
if (sfProp.IsSet()) {
return sfProp.IsOn();
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 6953ec6..1abdd0b 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -435,14 +435,6 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
target->CheckCxxModuleStatus(c);
}
- if (target->HaveCxx20ModuleSources() && !this->SupportsCxxModuleDyndep()) {
- root->GetMakefile()->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("The target named \"", target->GetName(),
- "\" contains C++ sources that export modules which is not "
- "supported by the generator"));
- }
-
// handle external vc project files
cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT");
if (expath) {
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 90b8839..5076e6c 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1384,14 +1384,6 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
gtgt->CheckCxxModuleStatus(configName);
}
- if (gtgt->HaveCxx20ModuleSources()) {
- gtgt->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("The target named \"", gtgt->GetName(),
- "\" contains C++ sources that export modules which is not "
- "supported by the generator"));
- }
-
auto& gtgt_visited = this->CommandsVisited[gtgt];
auto const& deps = this->GetTargetDirectDepends(gtgt);
for (auto const& d : deps) {
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index caa5e67..0c2a719 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -204,14 +204,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
this->GeneratorTarget->CheckCxxModuleStatus(this->GetConfigName());
- if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("The target named \"", this->GeneratorTarget->GetName(),
- "\" contains C++ sources that export modules which is not "
- "supported by the generator"));
- }
-
// -- Write the custom commands for this target
// Evaluates generator expressions and expands prop_value
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 2a54a55..ce94fe1 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -362,15 +362,6 @@ void cmVisualStudio10TargetGenerator::Generate()
this->GeneratorTarget->CheckCxxModuleStatus(config);
}
- if (this->GeneratorTarget->HaveCxx20ModuleSources() &&
- !this->GlobalGenerator->SupportsCxxModuleDyndep()) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("The target named \"", this->GeneratorTarget->GetName(),
- "\" contains C++ sources that export modules which is not "
- "supported by the generator"));
- }
-
this->ProjectType = computeProjectType(this->GeneratorTarget);
this->Managed = this->ProjectType == VsProjectType::csproj;
const std::string ProjectFileExtension =
diff --git a/Tests/RunCMake/CXXModules/NoCXX-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
index 5b609a9..da65c26 100644
--- a/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
@@ -1,13 +1,8 @@
-CMake Error in CMakeLists.txt:
- The target named "nocxx" has C\+\+ sources that export modules but the "CXX"
+(CMake Error in CMakeLists.txt:
+( The target named "nocxx" has C\+\+ sources that use modules but the "CXX"
language has not been enabled
-
-(
-CMake Error in CMakeLists.txt:
-( The target named "nocxx" has C\+\+ sources that export modules but the "CXX"
- language has not been enabled
-| The target named "nocxx" contains C\+\+ sources that export modules which is
- not supported by the generator
+| The target named "nocxx" contains C\+\+ sources that use modules which is not
+ supported by the generator
| Target "nocxx" has source file
.*/Tests/RunCMake/CXXModules/sources/module.cxx
diff --git a/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
index 4a1641b8..5a9b6e7 100644
--- a/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
@@ -1,15 +1,9 @@
-CMake Error in CMakeLists.txt:
- The target named "nocxx20" has C\+\+ sources that export modules but does not
+(CMake Error in CMakeLists.txt:
+( The target named "nocxx20" has C\+\+ sources that use modules but does not
include "cxx_std_20" \(or newer\) among its `target_compile_features`; found
"cxx_std_17"
-
-(
-CMake Error in CMakeLists.txt:
-( The target named "nocxx20" has C\+\+ sources that export modules but does not
- include "cxx_std_20" \(or newer\) among its `target_compile_features`; found
- "cxx_std_17"
-| The target named "nocxx20" contains C\+\+ sources that export modules which
- is not supported by the generator
+| The target named "nocxx20" contains C\+\+ sources that use modules which is
+ not supported by the generator
)
)*
CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt b/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
index 6640c99..6a9c995 100644
--- a/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
+++ b/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
@@ -6,13 +6,13 @@
due to lack of required features. Ninja 1.11 or higher is required.
|CMake Error in CMakeLists.txt:
- The target named "nodyndep" contains C\+\+ sources that export modules which
- is not supported by the generator
+ The target named "nodyndep" contains C\+\+ sources that use modules which is
+ not supported by the generator
(
CMake Error in CMakeLists.txt:
- The target named "nodyndep" contains C\+\+ sources that export modules which
- is not supported by the generator
+ The target named "nodyndep" contains C\+\+ sources that use modules which is
+ not supported by the generator
)*)
CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-result.txt b/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-stderr.txt b/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-stderr.txt
new file mode 100644
index 0000000..464627c
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty-stderr.txt
@@ -0,0 +1,9 @@
+(CMake Error in CMakeLists.txt:
+( The target named "noscanning-sf-property" has C\+\+ sources that use modules
+ but the compiler does not provide a way to discover the import graph
+ dependencies
+| The target named "noscanning-sf-property" contains C\+\+ sources that use modules which
+ is not supported by the generator
+)
+)*
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty.cmake b/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty.cmake
new file mode 100644
index 0000000..f356a11
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoScanningSourceFileProperty.cmake
@@ -0,0 +1,13 @@
+enable_language(CXX)
+unset(CMAKE_CXX_SCANDEP_SOURCE)
+
+add_executable(noscanning-sf-property
+ sources/module-use.cxx)
+set_target_properties(noscanning-sf-property
+ PROPERTIES
+ CXX_STANDARD 20
+ CXX_STANDARD_REQUIRED ON
+ CXX_SCAN_FOR_MODULES 0)
+set_source_files_properties(sources/module-use.cxx
+ PROPERTIES
+ CXX_SCAN_FOR_MODULES 1)
diff --git a/Tests/RunCMake/CXXModules/NoScanningTargetProperty-result.txt b/Tests/RunCMake/CXXModules/NoScanningTargetProperty-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoScanningTargetProperty-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/NoScanningTargetProperty-stderr.txt b/Tests/RunCMake/CXXModules/NoScanningTargetProperty-stderr.txt
new file mode 100644
index 0000000..72c7a0a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoScanningTargetProperty-stderr.txt
@@ -0,0 +1,9 @@
+(CMake Error in CMakeLists.txt:
+( The target named "noscanning-target-property" has C\+\+ sources that use
+ modules but the compiler does not provide a way to discover the import
+ graph dependencies
+| The target named "noscanning-target-property" contains C\+\+ sources that use modules which
+ is not supported by the generator
+)
+)*
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoScanningTargetProperty.cmake b/Tests/RunCMake/CXXModules/NoScanningTargetProperty.cmake
new file mode 100644
index 0000000..97a3d44
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoScanningTargetProperty.cmake
@@ -0,0 +1,10 @@
+enable_language(CXX)
+unset(CMAKE_CXX_SCANDEP_SOURCE)
+
+add_executable(noscanning-target-property
+ sources/module-use.cxx)
+set_target_properties(noscanning-target-property
+ PROPERTIES
+ CXX_STANDARD 20
+ CXX_STANDARD_REQUIRED ON
+ CXX_SCAN_FOR_MODULES 1)
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
index 2f32312..a697659 100644
--- a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -14,6 +14,9 @@ if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
if (NOT forced_cxx_standard)
run_cmake(NoCXX20)
endif ()
+
+ run_cmake(NoScanningSourceFileProperty)
+ run_cmake(NoScanningTargetProperty)
endif ()
if (RunCMake_GENERATOR MATCHES "Ninja")