diff options
author | Ben Boeckel <ben.boeckel@kitware.com> | 2023-02-01 15:40:19 (GMT) |
---|---|---|
committer | Ben Boeckel <ben.boeckel@kitware.com> | 2023-08-17 18:42:54 (GMT) |
commit | 9b9ec70b5421e8cf91e000d8b6636d7b0b721d1a (patch) | |
tree | aa5bea33938b0edb179ebdab0bcae0290ab3dcd2 /Source/cmNinjaNormalTargetGenerator.cxx | |
parent | 80ef50a1919d62acb82a6423c40042a94edeac60 (diff) | |
download | CMake-9b9ec70b5421e8cf91e000d8b6636d7b0b721d1a.zip CMake-9b9ec70b5421e8cf91e000d8b6636d7b0b721d1a.tar.gz CMake-9b9ec70b5421e8cf91e000d8b6636d7b0b721d1a.tar.bz2 |
Ninja: generate scanning and build rules for C++20 module synthetic targets
Diffstat (limited to 'Source/cmNinjaNormalTargetGenerator.cxx')
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 97 |
1 files changed, 85 insertions, 12 deletions
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 089498b..48c30b6 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -62,12 +62,15 @@ cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default; void cmNinjaNormalTargetGenerator::Generate(const std::string& config) { - std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); - if (this->TargetLinkLanguage(config).empty()) { - cmSystemTools::Error( - cmStrCat("CMake can not determine linker language for target: ", - this->GetGeneratorTarget()->GetName())); - return; + if (this->GetGeneratorTarget()->GetType() != + cmStateEnums::INTERFACE_LIBRARY) { + std::string lang = this->GeneratorTarget->GetLinkerLanguage(config); + if (this->TargetLinkLanguage(config).empty()) { + cmSystemTools::Error( + cmStrCat("CMake can not determine linker language for target: ", + this->GetGeneratorTarget()->GetName())); + return; + } } // Write the rules for each language. @@ -87,6 +90,34 @@ void cmNinjaNormalTargetGenerator::Generate(const std::string& config) if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) { this->WriteObjectLibStatement(config); + } else if (this->GetGeneratorTarget()->GetType() == + cmStateEnums::INTERFACE_LIBRARY) { + bool haveCxxModuleSources = false; + if (this->GetGeneratorTarget()->HaveCxx20ModuleSources()) { + haveCxxModuleSources = true; + } + + if (!haveCxxModuleSources) { + cmSystemTools::Error(cmStrCat( + "Ninja does not support INTERFACE libraries without C++ module " + "sources as a normal target: ", + this->GetGeneratorTarget()->GetName())); + return; + } + + firstForConfig = true; + for (auto const& fileConfig : this->GetConfigNames()) { + if (!this->GetGlobalGenerator() + ->GetCrossConfigs(fileConfig) + .count(config)) { + continue; + } + if (haveCxxModuleSources) { + this->WriteCxxModuleLibraryStatement(config, fileConfig, + firstForConfig); + } + firstForConfig = false; + } } else { firstForConfig = true; for (auto const& fileConfig : this->GetConfigNames()) { @@ -123,12 +154,26 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules( #endif // Write rules for languages compiled in this target. - std::set<std::string> languages; - std::vector<cmSourceFile const*> sourceFiles; - this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config); - if (this->HaveRequiredLanguages(sourceFiles, languages)) { - for (std::string const& language : languages) { - this->WriteLanguageRules(language, config); + { + std::set<std::string> languages; + std::vector<cmSourceFile const*> sourceFiles; + this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config); + if (this->HaveRequiredLanguages(sourceFiles, languages)) { + for (std::string const& language : languages) { + this->WriteLanguageRules(language, config); + } + } + } + + // Write rules for languages in BMI-only rules. + { + std::set<std::string> languages; + std::vector<cmSourceFile const*> sourceFiles; + this->GetGeneratorTarget()->GetCxxModuleSources(sourceFiles, config); + if (this->HaveRequiredLanguages(sourceFiles, languages)) { + for (std::string const& language : languages) { + this->WriteLanguageRules(language, config); + } } } } @@ -1637,6 +1682,34 @@ void cmNinjaNormalTargetGenerator::WriteObjectLibStatement( this->GetTargetName(), this->GetGeneratorTarget(), config); } +void cmNinjaNormalTargetGenerator::WriteCxxModuleLibraryStatement( + const std::string& config, const std::string& /*fileConfig*/, + bool firstForConfig) +{ + // TODO: How to use `fileConfig` properly? + + // Write a phony output that depends on the scanning output. + { + cmNinjaBuild build("phony"); + build.Comment = + cmStrCat("Imported C++ module library ", this->GetTargetName()); + this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(), + build.Outputs, config); + if (firstForConfig) { + this->GetLocalGenerator()->AppendTargetOutputs( + this->GetGeneratorTarget(), + this->GetGlobalGenerator()->GetByproductsForCleanTarget(config), + config); + } + build.ExplicitDeps.emplace_back(this->GetDyndepFilePath("CXX", config)); + this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), build); + } + + // Add aliases for the target name. + this->GetGlobalGenerator()->AddTargetAlias( + this->GetTargetName(), this->GetGeneratorTarget(), config); +} + cmGeneratorTarget::Names cmNinjaNormalTargetGenerator::TargetNames( const std::string& config) const { |