mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 05:11:15 -06:00
Merge topic 'cxxmodules-refactor-detection-support'
e37ff5694ccmGeneratorTarget: factor out fileset info and scanning detection9e61fc3d6dcmGeneratorTarget: factor out dyndep support detection5e026739e1cmGlobalGenerator: factor out C++ module support checking Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Merge-request: !7951
This commit is contained in:
@@ -8869,3 +8869,101 @@ void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::NeedCxxModuleSupport(std::string const& lang,
|
||||
std::string const& config) const
|
||||
{
|
||||
if (lang != "CXX"_s) {
|
||||
return false;
|
||||
}
|
||||
return this->HaveCxxModuleSupport(config) == Cxx20SupportLevel::Supported &&
|
||||
this->GetGlobalGenerator()->CheckCxxModuleSupport();
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::NeedDyndep(std::string const& lang,
|
||||
std::string const& config) const
|
||||
{
|
||||
return lang == "Fortran"_s || this->NeedCxxModuleSupport(lang, config);
|
||||
}
|
||||
|
||||
cmFileSet const* cmGeneratorTarget::GetFileSetForSource(
|
||||
std::string const& config, cmSourceFile const* sf) const
|
||||
{
|
||||
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 cmGeneratorTarget::NeedDyndepForSource(std::string const& lang,
|
||||
std::string const& config,
|
||||
cmSourceFile const* sf) const
|
||||
{
|
||||
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->GetProperty("CXX_SCAN_FOR_MODULES");
|
||||
if (tgtProp.IsSet()) {
|
||||
return tgtProp.IsOn();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::BuildFileSetInfoCache(std::string const& config) const
|
||||
{
|
||||
auto& per_config = this->Configs[config];
|
||||
|
||||
if (per_config.BuiltFileSetCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto const* tgt = this->Target;
|
||||
|
||||
for (auto const& name : tgt->GetAllFileSetNames()) {
|
||||
auto const* file_set = tgt->GetFileSet(name);
|
||||
if (!file_set) {
|
||||
tgt->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);
|
||||
|
||||
std::map<std::string, std::vector<std::string>> files;
|
||||
for (auto const& entry : fileEntries) {
|
||||
file_set->EvaluateFileEntry(directories, files, entry,
|
||||
this->LocalGenerator, config, this);
|
||||
}
|
||||
|
||||
for (auto const& it : files) {
|
||||
for (auto const& filename : it.second) {
|
||||
per_config.FileSetCache[filename] = file_set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
per_config.BuiltFileSetCache = true;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
enum class cmBuildStep;
|
||||
class cmComputeLinkInformation;
|
||||
class cmCustomCommand;
|
||||
class cmFileSet;
|
||||
class cmGlobalGenerator;
|
||||
class cmLocalGenerator;
|
||||
class cmMakefile;
|
||||
@@ -1229,4 +1230,21 @@ public:
|
||||
|
||||
// Check C++ module status for the target.
|
||||
void CheckCxxModuleStatus(std::string const& config) const;
|
||||
|
||||
bool NeedCxxModuleSupport(std::string const& lang,
|
||||
std::string const& config) const;
|
||||
bool NeedDyndep(std::string const& lang, std::string const& config) const;
|
||||
cmFileSet const* GetFileSetForSource(std::string const& config,
|
||||
cmSourceFile const* sf) const;
|
||||
bool NeedDyndepForSource(std::string const& lang, std::string const& config,
|
||||
cmSourceFile const* sf) const;
|
||||
|
||||
private:
|
||||
void BuildFileSetInfoCache(std::string const& config) const;
|
||||
struct InfoByConfig
|
||||
{
|
||||
bool BuiltFileSetCache = false;
|
||||
std::map<std::string, cmFileSet const*> FileSetCache;
|
||||
};
|
||||
mutable std::map<std::string, InfoByConfig> Configs;
|
||||
};
|
||||
|
||||
@@ -1439,6 +1439,19 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void cmGlobalGenerator::CxxModuleSupportCheck() const
|
||||
{
|
||||
bool const diagnose = !this->DiagnosedCxxModuleSupport &&
|
||||
!this->CMakeInstance->GetIsInTryCompile();
|
||||
if (diagnose) {
|
||||
this->DiagnosedCxxModuleSupport = true;
|
||||
this->GetCMakeInstance()->IssueMessage(
|
||||
MessageType::AUTHOR_WARNING,
|
||||
"C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP "
|
||||
"is experimental. It is meant only for compiler developers to try.");
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalGenerator::ComputeBuildFileGenerators()
|
||||
{
|
||||
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
|
||||
@@ -1597,6 +1610,8 @@ void cmGlobalGenerator::Generate()
|
||||
// it builds by default.
|
||||
this->InitializeProgressMarks();
|
||||
|
||||
this->DiagnosedCxxModuleSupport = false;
|
||||
|
||||
this->ProcessEvaluationFiles();
|
||||
|
||||
this->CMakeInstance->UpdateProgress("Generating", 0.1f);
|
||||
|
||||
@@ -157,6 +157,8 @@ public:
|
||||
|
||||
virtual bool InspectConfigTypeVariables() { return true; }
|
||||
|
||||
virtual bool CheckCxxModuleSupport() { return false; }
|
||||
|
||||
bool Compute();
|
||||
virtual void AddExtraIDETargets() {}
|
||||
|
||||
@@ -621,6 +623,8 @@ protected:
|
||||
|
||||
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
|
||||
|
||||
void CxxModuleSupportCheck() const;
|
||||
|
||||
/// @brief Qt AUTOMOC/UIC/RCC target generation
|
||||
/// @return true on success
|
||||
bool QtAutoGen();
|
||||
@@ -728,6 +732,8 @@ private:
|
||||
std::map<std::string, int> LanguageToLinkerPreference;
|
||||
std::map<std::string, std::string> LanguageToOriginalSharedLibFlags;
|
||||
|
||||
mutable bool DiagnosedCxxModuleSupport = false;
|
||||
|
||||
// Deferral id generation.
|
||||
size_t NextDeferId = 0;
|
||||
|
||||
|
||||
@@ -591,7 +591,7 @@ void cmGlobalNinjaGenerator::Generate()
|
||||
this->TargetAll = this->NinjaOutputPath("all");
|
||||
this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
|
||||
this->DisableCleandead = false;
|
||||
this->DiagnosedCxxModuleSupport = false;
|
||||
this->DiagnosedCxxModuleNinjaSupport = false;
|
||||
|
||||
this->PolicyCMP0058 =
|
||||
this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus(
|
||||
@@ -850,18 +850,12 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
|
||||
|
||||
bool cmGlobalNinjaGenerator::CheckCxxModuleSupport()
|
||||
{
|
||||
bool const diagnose = !this->DiagnosedCxxModuleSupport &&
|
||||
!this->CMakeInstance->GetIsInTryCompile();
|
||||
if (diagnose) {
|
||||
this->DiagnosedCxxModuleSupport = true;
|
||||
this->GetCMakeInstance()->IssueMessage(
|
||||
MessageType::AUTHOR_WARNING,
|
||||
"C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP "
|
||||
"is experimental. It is meant only for compiler developers to try.");
|
||||
}
|
||||
this->CxxModuleSupportCheck();
|
||||
if (this->NinjaSupportsDyndeps) {
|
||||
return true;
|
||||
}
|
||||
bool const diagnose = !this->DiagnosedCxxModuleNinjaSupport &&
|
||||
!this->CMakeInstance->GetIsInTryCompile();
|
||||
if (diagnose) {
|
||||
std::ostringstream e;
|
||||
/* clang-format off */
|
||||
|
||||
@@ -469,7 +469,7 @@ public:
|
||||
|
||||
bool IsSingleConfigUtility(cmGeneratorTarget const* target) const;
|
||||
|
||||
bool CheckCxxModuleSupport();
|
||||
bool CheckCxxModuleSupport() override;
|
||||
|
||||
protected:
|
||||
void Generate() override;
|
||||
@@ -592,7 +592,7 @@ private:
|
||||
|
||||
codecvt::Encoding NinjaExpectedEncoding = codecvt::None;
|
||||
|
||||
bool DiagnosedCxxModuleSupport = false;
|
||||
bool DiagnosedCxxModuleNinjaSupport = false;
|
||||
|
||||
void InitOutputPathPrefix();
|
||||
|
||||
|
||||
@@ -157,107 +157,6 @@ std::string cmNinjaTargetGenerator::LanguageDyndepRule(
|
||||
'_', config);
|
||||
}
|
||||
|
||||
bool cmNinjaTargetGenerator::NeedCxxModuleSupport(
|
||||
std::string const& lang, std::string const& config) const
|
||||
{
|
||||
if (lang != "CXX"_s) {
|
||||
return false;
|
||||
}
|
||||
return this->GetGeneratorTarget()->HaveCxxModuleSupport(config) ==
|
||||
cmGeneratorTarget::Cxx20SupportLevel::Supported &&
|
||||
this->GetGlobalGenerator()->CheckCxxModuleSupport();
|
||||
}
|
||||
|
||||
bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang,
|
||||
std::string const& config) const
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -341,7 +240,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
|
||||
}
|
||||
|
||||
auto const* fs = this->GetFileSetForSource(config, source);
|
||||
auto const* fs = this->GeneratorTarget->GetFileSetForSource(config, source);
|
||||
if (fs &&
|
||||
(fs->GetType() == "CXX_MODULES"_s ||
|
||||
fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
|
||||
@@ -699,7 +598,7 @@ 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);
|
||||
bool const needDyndep = this->GetGeneratorTarget()->NeedDyndep(lang, config);
|
||||
|
||||
if (needDyndep) {
|
||||
this->WriteCompileRule(lang, config, WithScanning::Yes);
|
||||
@@ -1387,7 +1286,8 @@ 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);
|
||||
bool const needDyndep =
|
||||
this->GeneratorTarget->NeedDyndepForSource(language, config, source);
|
||||
|
||||
cmNinjaBuild objBuild(this->LanguageCompilerRule(
|
||||
language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "cmOSXBundleGenerator.h"
|
||||
|
||||
class cmCustomCommand;
|
||||
class cmFileSet;
|
||||
class cmGeneratedFileStream;
|
||||
class cmGeneratorTarget;
|
||||
class cmLocalNinjaGenerator;
|
||||
@@ -64,10 +63,6 @@ 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,
|
||||
@@ -82,13 +77,8 @@ protected:
|
||||
const std::string& config) const;
|
||||
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,
|
||||
std::string const& config) const;
|
||||
|
||||
std::string OrderDependsTargetForTarget(const std::string& config);
|
||||
|
||||
@@ -238,8 +228,6 @@ 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;
|
||||
|
||||
Reference in New Issue
Block a user