mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-28 18:09:42 -05:00
Merge topic 'cxx-scanning-properties'
a02d792c6ecxxmodules: add properties to control scanning008c09d6dbcmNinjaTargetGenerator: factor out determining the fileset of a source Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !7935
This commit is contained in:
@@ -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(
|
||||
@@ -173,6 +174,90 @@ bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang,
|
||||
return lang == "Fortran" || this->NeedCxxModuleSupport(lang, config);
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::BuildFileSetInfoCache(std::string const& config)
|
||||
{
|
||||
auto& per_config = this->Configs[config];
|
||||
|
||||
if (per_config.BuiltFileSetCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto const* tgt = this->GeneratorTarget->Target;
|
||||
|
||||
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) {
|
||||
per_config.FileSetCache[filename] = file_set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
per_config.BuiltFileSetCache = true;
|
||||
}
|
||||
|
||||
cmFileSet const* cmNinjaTargetGenerator::GetFileSetForSource(
|
||||
std::string const& config, cmSourceFile const* sf)
|
||||
{
|
||||
this->BuildFileSetInfoCache(config);
|
||||
|
||||
auto const& path = sf->GetFullPath();
|
||||
auto const& per_config = this->Configs[config];
|
||||
|
||||
auto const fsit = per_config.FileSetCache.find(path);
|
||||
if (fsit == per_config.FileSetCache.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -256,54 +341,17 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
|
||||
}
|
||||
|
||||
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) {
|
||||
auto const* fs = this->GetFileSetForSource(config, source);
|
||||
if (fs &&
|
||||
(fs->GetType() == "CXX_MODULES"_s ||
|
||||
fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
|
||||
if (source->GetLanguage() != "CXX"_s) {
|
||||
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 == "CXX_MODULES"_s ||
|
||||
file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
|
||||
if (source->GetLanguage() != "CXX"_s) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"Target \"", tgt->GetName(), "\" contains the source\n ", path,
|
||||
"\nin a file set of type \"", file_set_type,
|
||||
R"(" but the source is not classified as a "CXX" source.)"));
|
||||
continue;
|
||||
}
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Target \"", this->GeneratorTarget->Target->GetName(),
|
||||
"\" contains the source\n ", source->GetFullPath(),
|
||||
"\nin a file set of type \"", fs->GetType(),
|
||||
R"(" but the source is not classified as a "CXX" source.)"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,6 +697,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();
|
||||
@@ -669,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";
|
||||
@@ -707,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"));
|
||||
|
||||
@@ -813,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";
|
||||
@@ -867,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>",
|
||||
@@ -1327,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);
|
||||
@@ -1437,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);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "cmOSXBundleGenerator.h"
|
||||
|
||||
class cmCustomCommand;
|
||||
class cmFileSet;
|
||||
class cmGeneratedFileStream;
|
||||
class cmGeneratorTarget;
|
||||
class cmLocalNinjaGenerator;
|
||||
@@ -63,8 +64,18 @@ protected:
|
||||
|
||||
cmMakefile* GetMakefile() const { return this->Makefile; }
|
||||
|
||||
void BuildFileSetInfoCache(std::string const& config);
|
||||
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,
|
||||
@@ -72,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,
|
||||
@@ -150,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);
|
||||
@@ -223,6 +238,8 @@ private:
|
||||
std::vector<cmCustomCommand const*> CustomCommands;
|
||||
cmNinjaDeps ExtraFiles;
|
||||
std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
|
||||
bool BuiltFileSetCache = false;
|
||||
std::map<std::string, cmFileSet const*> FileSetCache;
|
||||
};
|
||||
|
||||
std::map<std::string, ByConfig> Configs;
|
||||
|
||||
@@ -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", "");
|
||||
|
||||
Reference in New Issue
Block a user