summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2022-11-17 18:50:24 (GMT)
committerBen Boeckel <ben.boeckel@kitware.com>2022-11-18 12:54:31 (GMT)
commita02d792c6e9bf9200ab652db6b6da415d80b578c (patch)
tree6c9d224ad9d3f53ca53cbf0e51b7092834c4308d /Source
parent008c09d6db60f7c24781b47414ffa26edbd0e22d (diff)
downloadCMake-a02d792c6e9bf9200ab652db6b6da415d80b578c.zip
CMake-a02d792c6e9bf9200ab652db6b6da415d80b578c.tar.gz
CMake-a02d792c6e9bf9200ab652db6b6da415d80b578c.tar.bz2
cxxmodules: add properties to control scanning
The `CXX_SCAN_FOR_MODULES` property may be used to control scanning for targets and for source files rather than assuming "C++20 always needs to be scanned".
Diffstat (limited to 'Source')
-rw-r--r--Source/cmNinjaTargetGenerator.cxx56
-rw-r--r--Source/cmNinjaTargetGenerator.h13
-rw-r--r--Source/cmTarget.cxx1
3 files changed, 61 insertions, 9 deletions
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index ce73c17..d39e155 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -109,12 +109,13 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
}
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
- const std::string& lang, const std::string& config) const
+ const std::string& lang, const std::string& config,
+ WithScanning withScanning) const
{
return cmStrCat(
lang, "_COMPILER__",
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
- '_', config);
+ withScanning == WithScanning::Yes ? "_scanned_" : "_unscanned_", config);
}
std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
@@ -231,6 +232,32 @@ cmFileSet const* cmNinjaTargetGenerator::GetFileSetForSource(
return fsit->second;
}
+bool cmNinjaTargetGenerator::NeedDyndepForSource(std::string const& lang,
+ std::string const& config,
+ cmSourceFile const* sf)
+{
+ bool const needDyndep = this->NeedDyndep(lang, config);
+ if (!needDyndep) {
+ return false;
+ }
+ auto const* fs = this->GetFileSetForSource(config, sf);
+ if (fs &&
+ (fs->GetType() == "CXX_MODULES"_s ||
+ fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
+ return true;
+ }
+ auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
+ if (sfProp.IsSet()) {
+ return sfProp.IsOn();
+ }
+ auto const tgtProp =
+ this->GeneratorTarget->GetProperty("CXX_SCAN_FOR_MODULES");
+ if (tgtProp.IsSet()) {
+ return tgtProp.IsOn();
+ }
+ return true;
+}
+
std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
const std::string& config)
{
@@ -671,6 +698,19 @@ cmNinjaRule GetScanRule(
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const std::string& config)
{
+ // For some cases we scan to dynamically discover dependencies.
+ bool const needDyndep = this->NeedDyndep(lang, config);
+
+ if (needDyndep) {
+ this->WriteCompileRule(lang, config, WithScanning::Yes);
+ }
+ this->WriteCompileRule(lang, config, WithScanning::No);
+}
+
+void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
+ const std::string& config,
+ WithScanning withScanning)
+{
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
@@ -690,7 +730,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmMakefile* mf = this->GetMakefile();
// For some cases we scan to dynamically discover dependencies.
- bool const needDyndep = this->NeedDyndep(lang, config);
bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang);
std::string flags = "$FLAGS";
@@ -728,7 +767,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
- if (needDyndep) {
+ if (withScanning == WithScanning::Yes) {
const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
@@ -834,7 +873,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
this->GetGlobalGenerator()->AddRule(rule);
}
- cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
+ cmNinjaRule rule(this->LanguageCompilerRule(lang, config, withScanning));
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
@@ -888,7 +927,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
}
}
- if (needDyndep && !modmapFormat.empty()) {
+ if (withScanning == WithScanning::Yes && !modmapFormat.empty()) {
std::string modmapFlags = mf->GetRequiredDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
@@ -1348,8 +1387,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
!(language == "RC" || (language == "CUDA" && !flag));
int const commandLineLengthLimit =
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
+ bool const needDyndep = this->NeedDyndepForSource(language, config, source);
- cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
+ cmNinjaBuild objBuild(this->LanguageCompilerRule(
+ language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
cmNinjaVars& vars = objBuild.Variables;
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
vars["DEFINES"] = this->ComputeDefines(source, language, config);
@@ -1458,7 +1499,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
// For some cases we scan to dynamically discover dependencies.
- bool const needDyndep = this->NeedDyndep(language, config);
bool const compilationPreprocesses =
!this->NeedExplicitPreprocessing(language);
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index bb75fb3..d09f04b 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -19,6 +19,7 @@
#include "cmOSXBundleGenerator.h"
class cmCustomCommand;
+class cmFileSet;
class cmGeneratedFileStream;
class cmGeneratorTarget;
class cmLocalNinjaGenerator;
@@ -67,8 +68,14 @@ protected:
cmFileSet const* GetFileSetForSource(std::string const& config,
cmSourceFile const* sf);
+ enum class WithScanning
+ {
+ No,
+ Yes,
+ };
std::string LanguageCompilerRule(const std::string& lang,
- const std::string& config) const;
+ const std::string& config,
+ WithScanning withScanning) const;
std::string LanguagePreprocessAndScanRule(std::string const& lang,
const std::string& config) const;
std::string LanguageScanRule(std::string const& lang,
@@ -76,6 +83,8 @@ protected:
std::string LanguageDyndepRule(std::string const& lang,
const std::string& config) const;
bool NeedDyndep(std::string const& lang, std::string const& config) const;
+ bool NeedDyndepForSource(std::string const& lang, std::string const& config,
+ cmSourceFile const* sf);
bool NeedExplicitPreprocessing(std::string const& lang) const;
bool CompileWithDefines(std::string const& lang) const;
bool NeedCxxModuleSupport(std::string const& lang,
@@ -154,6 +163,8 @@ protected:
const std::string& config);
void WriteCompileRule(const std::string& language,
const std::string& config);
+ void WriteCompileRule(const std::string& language, const std::string& config,
+ WithScanning withScanning);
void WriteObjectBuildStatements(const std::string& config,
const std::string& fileConfig,
bool firstForConfig);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 2955d7c..70a624d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -526,6 +526,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("ANDROID_ANT_ADDITIONAL_OPTIONS");
initProp("BUILD_RPATH");
initProp("BUILD_RPATH_USE_ORIGIN");
+ initProp("CXX_SCAN_FOR_MODULES");
initProp("INSTALL_NAME_DIR");
initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
initPropValue("INSTALL_RPATH", "");