diff options
Diffstat (limited to 'Source/cmNinjaTargetGenerator.cxx')
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 83 |
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); |