mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 19:00:54 -06:00
Ninja: generate scanning and build rules for C++20 module synthetic targets
This commit is contained in:
@@ -2643,7 +2643,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
||||
for (cmScanDepInfo const& object : objects) {
|
||||
for (auto const& p : object.Provides) {
|
||||
std::string mod;
|
||||
if (!p.CompiledModulePath.empty()) {
|
||||
if (cmDyndepCollation::IsBmiOnly(export_info, object.PrimaryOutput)) {
|
||||
mod = object.PrimaryOutput;
|
||||
} else if (!p.CompiledModulePath.empty()) {
|
||||
// The scanner provided the path to the module file.
|
||||
mod = p.CompiledModulePath;
|
||||
if (!cmSystemTools::FileIsFullPath(mod)) {
|
||||
@@ -2714,8 +2716,12 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
|
||||
build.Outputs[0] = this->ConvertToNinjaPath(object.PrimaryOutput);
|
||||
build.ImplicitOuts.clear();
|
||||
for (auto const& p : object.Provides) {
|
||||
build.ImplicitOuts.push_back(
|
||||
this->ConvertToNinjaPath(mod_files[p.LogicalName].BmiPath));
|
||||
auto const implicitOut =
|
||||
this->ConvertToNinjaPath(mod_files[p.LogicalName].BmiPath);
|
||||
// Ignore the `provides` when the BMI is the output.
|
||||
if (implicitOut != build.Outputs[0]) {
|
||||
build.ImplicitOuts.emplace_back(implicitOut);
|
||||
}
|
||||
}
|
||||
build.ImplicitDeps.clear();
|
||||
for (auto const& r : object.Requires) {
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -49,6 +49,9 @@ private:
|
||||
const std::string& output);
|
||||
|
||||
void WriteObjectLibStatement(const std::string& config);
|
||||
void WriteCxxModuleLibraryStatement(const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
bool firstForConfig);
|
||||
|
||||
std::vector<std::string> ComputeLinkCmd(const std::string& config);
|
||||
std::vector<std::string> ComputeDeviceLinkCmd();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGlobalCommonGenerator.h"
|
||||
#include "cmGlobalNinjaGenerator.h"
|
||||
#include "cmList.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
@@ -59,8 +60,13 @@ std::unique_ptr<cmNinjaTargetGenerator> cmNinjaTargetGenerator::New(
|
||||
case cmStateEnums::OBJECT_LIBRARY:
|
||||
return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
|
||||
|
||||
case cmStateEnums::UTILITY:
|
||||
case cmStateEnums::INTERFACE_LIBRARY:
|
||||
if (target->HaveCxx20ModuleSources()) {
|
||||
return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
|
||||
}
|
||||
CM_FALLTHROUGH;
|
||||
|
||||
case cmStateEnums::UTILITY:
|
||||
case cmStateEnums::GLOBAL_TARGET:
|
||||
return cm::make_unique<cmNinjaUtilityTargetGenerator>(target);
|
||||
|
||||
@@ -167,7 +173,7 @@ std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
|
||||
// Refactor it.
|
||||
std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
cmSourceFile const* source, const std::string& language,
|
||||
const std::string& config)
|
||||
const std::string& config, const std::string& objectFileName)
|
||||
{
|
||||
std::unordered_map<std::string, std::string> pchSources;
|
||||
std::vector<std::string> architectures =
|
||||
@@ -247,6 +253,18 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
"\nin a file set of type \"", fs->GetType(),
|
||||
R"(" but the source is not classified as a "CXX" source.)"));
|
||||
}
|
||||
|
||||
if (!this->GeneratorTarget->Target->IsNormal()) {
|
||||
auto flag = this->GetMakefile()->GetSafeDefinition(
|
||||
"CMAKE_EXPERIMENTAL_CXX_MODULE_BMI_ONLY_FLAG");
|
||||
cmRulePlaceholderExpander::RuleVariables compileObjectVars;
|
||||
compileObjectVars.Object = objectFileName.c_str();
|
||||
auto rulePlaceholderExpander =
|
||||
this->GetLocalGenerator()->CreateRulePlaceholderExpander();
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
|
||||
flag, compileObjectVars);
|
||||
this->LocalGenerator->AppendCompileOptions(flags, flag);
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
@@ -394,6 +412,31 @@ std::string cmNinjaTargetGenerator::GetObjectFilePath(
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetBmiFilePath(
|
||||
cmSourceFile const* source, const std::string& config) const
|
||||
{
|
||||
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
|
||||
if (!path.empty()) {
|
||||
path += '/';
|
||||
}
|
||||
|
||||
auto& importedConfigInfo = this->Configs.at(config).ImportedCxxModules;
|
||||
if (!importedConfigInfo.Initialized()) {
|
||||
std::string configUpper = cmSystemTools::UpperCase(config);
|
||||
std::string propName = cmStrCat("IMPORTED_CXX_MODULES_", configUpper);
|
||||
auto value = this->GeneratorTarget->GetSafeProperty(propName);
|
||||
importedConfigInfo.Initialize(value);
|
||||
}
|
||||
|
||||
std::string bmiName =
|
||||
importedConfigInfo.BmiNameForSource(source->GetFullPath());
|
||||
|
||||
path += cmStrCat(
|
||||
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
|
||||
this->GetGlobalGenerator()->ConfigDirectory(config), '/', bmiName);
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::GetClangTidyReplacementsFilePath(
|
||||
std::string const& directory, cmSourceFile const& source,
|
||||
std::string const& config) const
|
||||
@@ -1027,6 +1070,16 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<cmSourceFile const*> bmiOnlySources;
|
||||
this->GeneratorTarget->GetCxxModuleSources(bmiOnlySources, config);
|
||||
|
||||
for (cmSourceFile const* sf : bmiOnlySources) {
|
||||
this->WriteCxxModuleBmiBuildStatement(sf, config, fileConfig,
|
||||
firstForConfig);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& langScanningFiles : this->Configs[config].ScanningInfo) {
|
||||
std::string const& language = langScanningFiles.first;
|
||||
std::vector<ScanningFiles> const& scanningFiles = langScanningFiles.second;
|
||||
@@ -1149,22 +1202,22 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
|
||||
scanBuild.Variables["OBJ_FILE"] = objectFileName;
|
||||
|
||||
// Tell dependency scanner where to store dyndep intermediate results.
|
||||
std::string const& ddiFile = cmStrCat(objectFileName, ".ddi");
|
||||
scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
|
||||
std::string ddiFileName = cmStrCat(objectFileName, ".ddi");
|
||||
scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFileName;
|
||||
|
||||
// Outputs of the scan/preprocessor build statement.
|
||||
if (compilePP) {
|
||||
scanBuild.Outputs.push_back(ppFileName);
|
||||
scanBuild.ImplicitOuts.push_back(ddiFile);
|
||||
scanBuild.ImplicitOuts.push_back(ddiFileName);
|
||||
} else {
|
||||
scanBuild.Outputs.push_back(ddiFile);
|
||||
scanBuild.Outputs.push_back(ddiFileName);
|
||||
scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName;
|
||||
if (!compilationPreprocesses) {
|
||||
// Compilation does not preprocess and we are not compiling an
|
||||
// already-preprocessed source. Make compilation depend on the scan
|
||||
// results to honor implicit dependencies discovered during scanning
|
||||
// (such as Fortran INCLUDE directives).
|
||||
objBuild.ImplicitDeps.emplace_back(ddiFile);
|
||||
objBuild.ImplicitDeps.emplace_back(ddiFileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1214,7 +1267,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
cmNinjaBuild objBuild(this->LanguageCompilerRule(
|
||||
language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
|
||||
cmNinjaVars& vars = objBuild.Variables;
|
||||
vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
|
||||
vars["FLAGS"] =
|
||||
this->ComputeFlagsForObject(source, language, config, objectFileName);
|
||||
vars["DEFINES"] = this->ComputeDefines(source, language, config);
|
||||
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
|
||||
|
||||
@@ -1545,6 +1599,155 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
}
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteCxxModuleBmiBuildStatement(
|
||||
cmSourceFile const* source, const std::string& config,
|
||||
const std::string& fileConfig, bool firstForConfig)
|
||||
{
|
||||
std::string const language = source->GetLanguage();
|
||||
if (language != "CXX"_s) {
|
||||
this->GetMakefile()->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Source file '", source->GetFullPath(), "' of target '",
|
||||
this->GetTargetName(), "' is a '", language,
|
||||
"' source but must be 'CXX' in order to have a BMI build "
|
||||
"statement generated."));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string const sourceFilePath = this->GetCompiledSourceNinjaPath(source);
|
||||
std::string const bmiDir = this->ConvertToNinjaPath(
|
||||
cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
|
||||
this->GetGlobalGenerator()->ConfigDirectory(config)));
|
||||
std::string const bmiFileName =
|
||||
this->ConvertToNinjaPath(this->GetBmiFilePath(source, config));
|
||||
std::string const bmiFileDir = cmSystemTools::GetFilenamePath(bmiFileName);
|
||||
|
||||
int const commandLineLengthLimit = this->ForceResponseFile() ? -1 : 0;
|
||||
|
||||
cmNinjaBuild bmiBuild(
|
||||
this->LanguageCompilerRule(language, config, WithScanning::Yes));
|
||||
cmNinjaVars& vars = bmiBuild.Variables;
|
||||
vars["FLAGS"] =
|
||||
this->ComputeFlagsForObject(source, language, config, bmiFileName);
|
||||
vars["DEFINES"] = this->ComputeDefines(source, language, config);
|
||||
vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
|
||||
|
||||
if (this->GetMakefile()->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_", language, "_DEPFILE_FORMAT")) != "msvc"_s) {
|
||||
bool replaceExt(false);
|
||||
if (!language.empty()) {
|
||||
std::string repVar =
|
||||
cmStrCat("CMAKE_", language, "_DEPFILE_EXTENSION_REPLACE");
|
||||
replaceExt = this->Makefile->IsOn(repVar);
|
||||
}
|
||||
if (!replaceExt) {
|
||||
// use original code
|
||||
vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
cmStrCat(bmiFileName, ".d"), cmOutputConverter::SHELL);
|
||||
} else {
|
||||
// Replace the original source file extension with the
|
||||
// depend file extension.
|
||||
std::string dependFileName = cmStrCat(
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(bmiFileName), ".d");
|
||||
vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
cmStrCat(bmiFileDir, '/', dependFileName), cmOutputConverter::SHELL);
|
||||
}
|
||||
}
|
||||
|
||||
std::string d =
|
||||
this->GeneratorTarget->GetClangTidyExportFixesDirectory(language);
|
||||
if (!d.empty()) {
|
||||
this->GlobalCommonGenerator->AddClangTidyExportFixesDir(d);
|
||||
std::string fixesFile =
|
||||
this->GetClangTidyReplacementsFilePath(d, *source, config);
|
||||
this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
|
||||
cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(fixesFile));
|
||||
fixesFile = this->ConvertToNinjaPath(fixesFile);
|
||||
vars["CLANG_TIDY_EXPORT_FIXES"] = fixesFile;
|
||||
}
|
||||
|
||||
if (firstForConfig) {
|
||||
this->ExportObjectCompileCommand(
|
||||
language, sourceFilePath, bmiDir, bmiFileName, bmiFileDir, vars["FLAGS"],
|
||||
vars["DEFINES"], vars["INCLUDES"], config);
|
||||
}
|
||||
|
||||
bmiBuild.Outputs.push_back(bmiFileName);
|
||||
bmiBuild.ExplicitDeps.push_back(sourceFilePath);
|
||||
|
||||
std::vector<std::string> depList;
|
||||
|
||||
std::vector<std::string> architectures =
|
||||
this->GeneratorTarget->GetAppleArchs(config, language);
|
||||
if (architectures.empty()) {
|
||||
architectures.emplace_back();
|
||||
}
|
||||
|
||||
bmiBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config));
|
||||
|
||||
// For some cases we scan to dynamically discover dependencies.
|
||||
std::string modmapFormat;
|
||||
if (true) {
|
||||
std::string const modmapFormatVar =
|
||||
cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT");
|
||||
modmapFormat = this->Makefile->GetSafeDefinition(modmapFormatVar);
|
||||
}
|
||||
|
||||
{
|
||||
bool const compilePPWithDefines = this->CompileWithDefines(language);
|
||||
|
||||
std::string scanRuleName = this->LanguageScanRule(language, config);
|
||||
std::string ppFileName = cmStrCat(bmiFileName, ".ddi.i");
|
||||
|
||||
cmNinjaBuild ppBuild = GetScanBuildStatement(
|
||||
scanRuleName, ppFileName, false, compilePPWithDefines, true, bmiBuild,
|
||||
vars, bmiFileName, this->LocalGenerator);
|
||||
|
||||
ScanningFiles scanningFiles;
|
||||
|
||||
if (firstForConfig) {
|
||||
scanningFiles.ScanningOutput = cmStrCat(bmiFileName, ".ddi");
|
||||
}
|
||||
|
||||
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
|
||||
ppBuild.Variables);
|
||||
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
|
||||
ppBuild, commandLineLengthLimit);
|
||||
|
||||
std::string const dyndep = this->GetDyndepFilePath(language, config);
|
||||
bmiBuild.OrderOnlyDeps.push_back(dyndep);
|
||||
vars["dyndep"] = dyndep;
|
||||
|
||||
if (!modmapFormat.empty()) {
|
||||
std::string ddModmapFile = cmStrCat(bmiFileName, ".modmap");
|
||||
vars["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile;
|
||||
scanningFiles.ModuleMapFile = std::move(ddModmapFile);
|
||||
}
|
||||
|
||||
if (!scanningFiles.IsEmpty()) {
|
||||
this->Configs[config].ScanningInfo[language].emplace_back(scanningFiles);
|
||||
}
|
||||
}
|
||||
|
||||
this->EnsureParentDirectoryExists(bmiFileName);
|
||||
|
||||
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
bmiDir, cmOutputConverter::SHELL);
|
||||
vars["OBJECT_FILE_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
bmiFileDir, cmOutputConverter::SHELL);
|
||||
|
||||
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
|
||||
vars);
|
||||
|
||||
this->SetMsvcTargetPdbVariable(vars, config);
|
||||
|
||||
bmiBuild.RspFile = cmStrCat(bmiFileName, ".rsp");
|
||||
|
||||
this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
|
||||
bmiBuild, commandLineLengthLimit);
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
|
||||
const std::string& config)
|
||||
{
|
||||
@@ -1605,6 +1808,9 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
|
||||
cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
|
||||
return this->GetObjectFilePath(sf, cnf);
|
||||
};
|
||||
cb.BmiFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
|
||||
return this->GetBmiFilePath(sf, cnf);
|
||||
};
|
||||
|
||||
#if !defined(CMAKE_BOOTSTRAP)
|
||||
cmDyndepCollation::AddCollationInformation(tdi, this->GeneratorTarget,
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "cmCommonTargetGenerator.h"
|
||||
#include "cmGlobalNinjaGenerator.h"
|
||||
#include "cmImportedCxxModuleInfo.h"
|
||||
#include "cmNinjaTypes.h"
|
||||
#include "cmOSXBundleGenerator.h"
|
||||
|
||||
@@ -91,7 +92,8 @@ protected:
|
||||
*/
|
||||
std::string ComputeFlagsForObject(cmSourceFile const* source,
|
||||
const std::string& language,
|
||||
const std::string& config);
|
||||
const std::string& config,
|
||||
const std::string& objectFileName);
|
||||
|
||||
void AddIncludeFlags(std::string& flags, std::string const& lang,
|
||||
const std::string& config) override;
|
||||
@@ -129,6 +131,8 @@ protected:
|
||||
/// @return the object file path for the given @a source.
|
||||
std::string GetObjectFilePath(cmSourceFile const* source,
|
||||
const std::string& config) const;
|
||||
std::string GetBmiFilePath(cmSourceFile const* source,
|
||||
const std::string& config) const;
|
||||
|
||||
/// @return the preprocessed source file path for the given @a source.
|
||||
std::string GetPreprocessedFilePath(cmSourceFile const* source,
|
||||
@@ -163,6 +167,10 @@ protected:
|
||||
void WriteObjectBuildStatements(const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
bool firstForConfig);
|
||||
void WriteCxxModuleBmiBuildStatement(cmSourceFile const* source,
|
||||
const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
bool firstForConfig);
|
||||
void WriteObjectBuildStatement(cmSourceFile const* source,
|
||||
const std::string& config,
|
||||
const std::string& fileConfig,
|
||||
@@ -239,6 +247,8 @@ private:
|
||||
cmNinjaDeps Objects;
|
||||
// Dyndep Support
|
||||
std::map<std::string, std::vector<ScanningFiles>> ScanningInfo;
|
||||
// Imported C++ module info.
|
||||
mutable ImportedCxxModuleLookup ImportedCxxModules;
|
||||
// Swift Support
|
||||
Json::Value SwiftOutputMap;
|
||||
std::vector<cmCustomCommand const*> CustomCommands;
|
||||
|
||||
Reference in New Issue
Block a user