summaryrefslogtreecommitdiffstats
path: root/Source/cmNinjaTargetGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmNinjaTargetGenerator.cxx')
-rw-r--r--Source/cmNinjaTargetGenerator.cxx83
1 files changed, 73 insertions, 10 deletions
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index e61b4b6..3fac7f5 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
+#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -28,6 +29,7 @@
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmNinjaNormalTargetGenerator.h"
#include "cmNinjaUtilityTargetGenerator.h"
#include "cmOutputConverter.h"
@@ -39,6 +41,7 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmValue.h"
#include "cmake.h"
@@ -252,6 +255,55 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
}
+ if (this->NeedCxxModuleSupport(language, config)) {
+ auto const& path = source->GetFullPath();
+ auto const* tgt = this->GeneratorTarget->Target;
+
+ std::string file_set_type;
+
+ for (auto const& name : tgt->GetAllFileSetNames()) {
+ auto const* file_set = tgt->GetFileSet(name);
+ if (!file_set) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target `", tgt->GetName(),
+ "` is tracked to have file set `", name,
+ "`, but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
+
+ std::map<std::string, std::vector<std::string>> files;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files, entry,
+ this->LocalGenerator, config,
+ this->GeneratorTarget);
+ }
+
+ for (auto const& it : files) {
+ for (auto const& filename : it.second) {
+ if (filename == path) {
+ file_set_type = file_set->GetType();
+ break;
+ }
+ }
+ }
+
+ if (!file_set_type.empty()) {
+ std::string source_type_var = cmStrCat(
+ "CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_", file_set_type);
+ cmMakefile* mf = this->GetMakefile();
+ if (cmValue source_type_flag = mf->GetDefinition(source_type_var)) {
+ this->LocalGenerator->AppendFlags(flags, *source_type_flag);
+ }
+ }
+ }
+ }
+
return flags;
}
@@ -534,6 +586,7 @@ std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
// not perform explicit preprocessing too.
cmNinjaRule GetScanRule(
std::string const& ruleName, std::string const& ppFileName,
+ std::string const& deptype,
cmRulePlaceholderExpander::RuleVariables const& vars,
const std::string& responseFlag, const std::string& flags,
cmRulePlaceholderExpander* const rulePlaceholderExpander,
@@ -542,8 +595,13 @@ cmNinjaRule GetScanRule(
{
cmNinjaRule rule(ruleName);
// Scanning always uses a depfile for preprocessor dependencies.
- rule.DepType = ""; // no deps= for multiple outputs
- rule.DepFile = "$DEP_FILE";
+ if (deptype == "msvc"_s) {
+ rule.DepType = deptype;
+ rule.DepFile = "";
+ } else {
+ rule.DepType = ""; // no deps= for multiple outputs
+ rule.DepFile = "$DEP_FILE";
+ }
cmRulePlaceholderExpander::RuleVariables scanVars;
scanVars.CMTargetName = vars.CMTargetName;
@@ -647,6 +705,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
if (needDyndep) {
+ const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
+
// Rule to scan dependencies of sources that need preprocessing.
{
std::vector<std::string> scanCommands;
@@ -674,10 +735,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
"$DYNDEP_INTERMEDIATE_FILE"));
}
- auto scanRule =
- GetScanRule(scanRuleName, ppFileName, vars, responseFlag, flags,
- rulePlaceholderExpander.get(), this->GetLocalGenerator(),
- std::move(scanCommands), config);
+ auto scanRule = GetScanRule(
+ scanRuleName, ppFileName, scanDepType, vars, responseFlag, flags,
+ rulePlaceholderExpander.get(), this->GetLocalGenerator(),
+ std::move(scanCommands), config);
scanRule.Comment =
cmStrCat("Rule for generating ", lang, " dependencies.");
@@ -705,9 +766,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
scanCommands.emplace_back(
GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out"));
- auto scanRule = GetScanRule(
- scanRuleName, "", vars, "", flags, rulePlaceholderExpander.get(),
- this->GetLocalGenerator(), std::move(scanCommands), config);
+ auto scanRule =
+ GetScanRule(scanRuleName, "", scanDepType, vars, "", flags,
+ rulePlaceholderExpander.get(), this->GetLocalGenerator(),
+ std::move(scanCommands), config);
// Write the rule for generating dependencies for the given language.
scanRule.Comment = cmStrCat("Rule for generating ", lang,
@@ -1197,7 +1259,8 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName;
}
- // Scanning always uses a depfile for preprocessor dependencies.
+ // Scanning always provides a depfile for preprocessor dependencies. This
+ // variable is unused in `msvc`-deptype scanners.
std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d");
scanBuild.Variables["DEP_FILE"] =
lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL);