mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-24 07:08:38 -05:00
Merge topic 'pch-ios-multi-arch'
f593b354da PCH: Add support for multi architecture iOS projects
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4561
This commit is contained in:
@@ -98,17 +98,20 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
|
||||
}
|
||||
|
||||
std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
|
||||
const std::string& config)
|
||||
const std::string& config,
|
||||
const std::string& arch)
|
||||
{
|
||||
auto i = this->Configs[config].FlagsByLanguage.find(l);
|
||||
if (i == this->Configs[config].FlagsByLanguage.end()) {
|
||||
const std::string key = config + arch;
|
||||
|
||||
auto i = this->Configs[key].FlagsByLanguage.find(l);
|
||||
if (i == this->Configs[key].FlagsByLanguage.end()) {
|
||||
std::string flags;
|
||||
|
||||
this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
|
||||
config, l, flags);
|
||||
config, l, flags, arch);
|
||||
|
||||
ByLanguageMap::value_type entry(l, flags);
|
||||
i = this->Configs[config].FlagsByLanguage.insert(entry).first;
|
||||
i = this->Configs[key].FlagsByLanguage.insert(entry).first;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ protected:
|
||||
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
|
||||
const char* name, bool so);
|
||||
|
||||
std::string GetFlags(const std::string& l, const std::string& config);
|
||||
std::string GetFlags(const std::string& l, const std::string& config,
|
||||
const std::string& arch = std::string());
|
||||
std::string GetDefines(const std::string& l, const std::string& config);
|
||||
std::string GetIncludes(std::string const& l, const std::string& config);
|
||||
std::string GetManifests(const std::string& config);
|
||||
|
||||
@@ -872,14 +872,27 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
|
||||
}
|
||||
|
||||
// Add precompile headers compile options.
|
||||
const std::string pchSource =
|
||||
this->GT->GetPchSource(this->Config, fd.Language);
|
||||
std::vector<std::string> architectures;
|
||||
this->GT->GetAppleArchs(this->Config, architectures);
|
||||
if (architectures.empty()) {
|
||||
architectures.emplace_back();
|
||||
}
|
||||
|
||||
if (!pchSource.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
std::unordered_map<std::string, std::string> pchSources;
|
||||
for (const std::string& arch : architectures) {
|
||||
const std::string pchSource =
|
||||
this->GT->GetPchSource(this->Config, fd.Language, arch);
|
||||
if (!pchSource.empty()) {
|
||||
pchSources.insert(std::make_pair(pchSource, arch));
|
||||
}
|
||||
}
|
||||
|
||||
if (!pchSources.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
std::string pchOptions;
|
||||
if (sf->ResolveFullPath() == pchSource) {
|
||||
pchOptions =
|
||||
this->GT->GetPchCreateCompileOptions(this->Config, fd.Language);
|
||||
auto pchIt = pchSources.find(sf->ResolveFullPath());
|
||||
if (pchIt != pchSources.end()) {
|
||||
pchOptions = this->GT->GetPchCreateCompileOptions(
|
||||
this->Config, fd.Language, pchIt->second);
|
||||
} else {
|
||||
pchOptions =
|
||||
this->GT->GetPchUseCompileOptions(this->Config, fd.Language);
|
||||
|
||||
@@ -3540,7 +3540,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
|
||||
const std::string& language) const
|
||||
const std::string& language,
|
||||
const std::string& arch) const
|
||||
{
|
||||
if (language != "C" && language != "CXX" && language != "OBJC" &&
|
||||
language != "OBJCXX") {
|
||||
@@ -3555,7 +3556,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
|
||||
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
|
||||
const auto inserted =
|
||||
this->PchHeaders.insert(std::make_pair(language + config, ""));
|
||||
this->PchHeaders.insert(std::make_pair(language + config + arch, ""));
|
||||
if (inserted.second) {
|
||||
const std::vector<BT<std::string>> headers =
|
||||
this->GetPrecompileHeaders(config, language);
|
||||
@@ -3587,7 +3588,8 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
|
||||
}
|
||||
|
||||
filename =
|
||||
cmStrCat(filename, "/cmake_pch", languageToExtension.at(language));
|
||||
cmStrCat(filename, "/cmake_pch", arch.empty() ? "" : cmStrCat("_", arch),
|
||||
languageToExtension.at(language));
|
||||
|
||||
const std::string filename_tmp = cmStrCat(filename, ".tmp");
|
||||
if (!pchReuseFrom) {
|
||||
@@ -3646,16 +3648,17 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchSource(const std::string& config,
|
||||
const std::string& language) const
|
||||
const std::string& language,
|
||||
const std::string& arch) const
|
||||
{
|
||||
if (language != "C" && language != "CXX" && language != "OBJC" &&
|
||||
language != "OBJCXX") {
|
||||
return std::string();
|
||||
}
|
||||
const auto inserted =
|
||||
this->PchSources.insert(std::make_pair(language + config, ""));
|
||||
this->PchSources.insert(std::make_pair(language + config + arch, ""));
|
||||
if (inserted.second) {
|
||||
const std::string pchHeader = this->GetPchHeader(config, language);
|
||||
const std::string pchHeader = this->GetPchHeader(config, language, arch);
|
||||
if (pchHeader.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
@@ -3682,13 +3685,15 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
|
||||
{ "OBJCXX", ".objcxx.hxx.mm" }
|
||||
};
|
||||
|
||||
filename += languageToExtension.at(language);
|
||||
filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
|
||||
languageToExtension.at(language));
|
||||
} else {
|
||||
const std::map<std::string, std::string> languageToExtension = {
|
||||
{ "C", ".c" }, { "CXX", ".cxx" }, { "OBJC", ".m" }, { "OBJCXX", ".mm" }
|
||||
};
|
||||
|
||||
filename += languageToExtension.at(language);
|
||||
filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
|
||||
languageToExtension.at(language));
|
||||
}
|
||||
|
||||
const std::string filename_tmp = cmStrCat(filename, ".tmp");
|
||||
@@ -3705,16 +3710,17 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
|
||||
const std::string& language)
|
||||
const std::string& language,
|
||||
const std::string& arch)
|
||||
{
|
||||
if (language != "C" && language != "CXX" && language != "OBJC" &&
|
||||
language != "OBJCXX") {
|
||||
return std::string();
|
||||
}
|
||||
const auto inserted =
|
||||
this->PchObjectFiles.insert(std::make_pair(language + config, ""));
|
||||
this->PchObjectFiles.insert(std::make_pair(language + config + arch, ""));
|
||||
if (inserted.second) {
|
||||
const std::string pchSource = this->GetPchSource(config, language);
|
||||
const std::string pchSource = this->GetPchSource(config, language, arch);
|
||||
if (pchSource.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
@@ -3731,10 +3737,11 @@ std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchFile(const std::string& config,
|
||||
const std::string& language)
|
||||
const std::string& language,
|
||||
const std::string& arch)
|
||||
{
|
||||
const auto inserted =
|
||||
this->PchFiles.insert(std::make_pair(language + config, ""));
|
||||
this->PchFiles.insert(std::make_pair(language + config + arch, ""));
|
||||
if (inserted.second) {
|
||||
std::string& pchFile = inserted.first->second;
|
||||
|
||||
@@ -3762,12 +3769,12 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
|
||||
}
|
||||
|
||||
const std::string pchFileObject =
|
||||
generatorTarget->GetPchFileObject(config, language);
|
||||
generatorTarget->GetPchFileObject(config, language, arch);
|
||||
if (!pchExtension.empty()) {
|
||||
pchFile = replaceExtension(pchFileObject, pchExtension);
|
||||
}
|
||||
} else {
|
||||
pchFile = this->GetPchHeader(config, language);
|
||||
pchFile = this->GetPchHeader(config, language, arch);
|
||||
pchFile += pchExtension;
|
||||
}
|
||||
}
|
||||
@@ -3775,10 +3782,11 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchCreateCompileOptions(
|
||||
const std::string& config, const std::string& language)
|
||||
const std::string& config, const std::string& language,
|
||||
const std::string& arch)
|
||||
{
|
||||
const auto inserted = this->PchCreateCompileOptions.insert(
|
||||
std::make_pair(language + config, ""));
|
||||
std::make_pair(language + config + arch, ""));
|
||||
if (inserted.second) {
|
||||
std::string& createOptionList = inserted.first->second;
|
||||
|
||||
@@ -3793,8 +3801,8 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions(
|
||||
createOptionList = cmStrCat(
|
||||
createOptionList, ";", this->Makefile->GetSafeDefinition(createOptVar));
|
||||
|
||||
const std::string pchHeader = this->GetPchHeader(config, language);
|
||||
const std::string pchFile = this->GetPchFile(config, language);
|
||||
const std::string pchHeader = this->GetPchHeader(config, language, arch);
|
||||
const std::string pchFile = this->GetPchFile(config, language, arch);
|
||||
|
||||
cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>", pchHeader);
|
||||
cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>", pchFile);
|
||||
@@ -3803,10 +3811,11 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions(
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchUseCompileOptions(
|
||||
const std::string& config, const std::string& language)
|
||||
const std::string& config, const std::string& language,
|
||||
const std::string& arch)
|
||||
{
|
||||
const auto inserted =
|
||||
this->PchUseCompileOptions.insert(std::make_pair(language + config, ""));
|
||||
const auto inserted = this->PchUseCompileOptions.insert(
|
||||
std::make_pair(language + config + arch, ""));
|
||||
if (inserted.second) {
|
||||
std::string& useOptionList = inserted.first->second;
|
||||
|
||||
@@ -3816,13 +3825,18 @@ std::string cmGeneratorTarget::GetPchUseCompileOptions(
|
||||
}
|
||||
|
||||
const std::string useOptVar =
|
||||
cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_USE_PCH");
|
||||
cmStrCat(language, "_COMPILE_OPTIONS_USE_PCH");
|
||||
|
||||
useOptionList = cmStrCat(useOptionList, ";",
|
||||
this->Makefile->GetSafeDefinition(useOptVar));
|
||||
const std::string useOptionListProperty = this->GetSafeProperty(useOptVar);
|
||||
|
||||
const std::string pchHeader = this->GetPchHeader(config, language);
|
||||
const std::string pchFile = this->GetPchFile(config, language);
|
||||
useOptionList = cmStrCat(
|
||||
useOptionList, ";",
|
||||
useOptionListProperty.empty()
|
||||
? this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_", useOptVar))
|
||||
: useOptionListProperty);
|
||||
|
||||
const std::string pchHeader = this->GetPchHeader(config, language, arch);
|
||||
const std::string pchFile = this->GetPchFile(config, language, arch);
|
||||
|
||||
cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>", pchHeader);
|
||||
cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>", pchFile);
|
||||
|
||||
@@ -478,17 +478,23 @@ public:
|
||||
const std::string& config, const std::string& language) const;
|
||||
|
||||
std::string GetPchHeader(const std::string& config,
|
||||
const std::string& language) const;
|
||||
const std::string& language,
|
||||
const std::string& arch = std::string()) const;
|
||||
std::string GetPchSource(const std::string& config,
|
||||
const std::string& language) const;
|
||||
const std::string& language,
|
||||
const std::string& arch = std::string()) const;
|
||||
std::string GetPchFileObject(const std::string& config,
|
||||
const std::string& language);
|
||||
const std::string& language,
|
||||
const std::string& arch = std::string());
|
||||
std::string GetPchFile(const std::string& config,
|
||||
const std::string& language);
|
||||
std::string GetPchCreateCompileOptions(const std::string& config,
|
||||
const std::string& language);
|
||||
const std::string& language,
|
||||
const std::string& arch = std::string());
|
||||
std::string GetPchCreateCompileOptions(
|
||||
const std::string& config, const std::string& language,
|
||||
const std::string& arch = std::string());
|
||||
std::string GetPchUseCompileOptions(const std::string& config,
|
||||
const std::string& language);
|
||||
const std::string& language,
|
||||
const std::string& arch = std::string());
|
||||
|
||||
void AddSourceFileToUnityBatch(const std::string& sourceFilename);
|
||||
bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const;
|
||||
|
||||
+181
-147
@@ -1520,16 +1520,17 @@ void cmLocalGenerator::GetTargetFlags(
|
||||
void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target,
|
||||
std::string const& config,
|
||||
std::string const& lang,
|
||||
std::string& flags)
|
||||
std::string& flags,
|
||||
std::string const& arch)
|
||||
{
|
||||
std::vector<BT<std::string>> tmpFlags =
|
||||
this->GetTargetCompileFlags(target, config, lang);
|
||||
this->GetTargetCompileFlags(target, config, lang, arch);
|
||||
this->AppendFlags(flags, tmpFlags);
|
||||
}
|
||||
|
||||
std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
|
||||
cmGeneratorTarget* target, std::string const& config,
|
||||
std::string const& lang)
|
||||
std::string const& lang, std::string const& arch)
|
||||
{
|
||||
std::vector<BT<std::string>> flags;
|
||||
std::string compileFlags;
|
||||
@@ -1543,7 +1544,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
|
||||
this->AppendFeatureOptions(compileFlags, lang, "IPO");
|
||||
}
|
||||
|
||||
this->AddArchitectureFlags(compileFlags, target, lang, config);
|
||||
this->AddArchitectureFlags(compileFlags, target, lang, config, arch);
|
||||
|
||||
if (lang == "Fortran") {
|
||||
this->AppendFlags(compileFlags,
|
||||
@@ -1771,7 +1772,8 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
|
||||
void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
|
||||
cmGeneratorTarget const* target,
|
||||
const std::string& lang,
|
||||
const std::string& config)
|
||||
const std::string& config,
|
||||
const std::string& filterArch)
|
||||
{
|
||||
// Only add Apple specific flags on Apple platforms
|
||||
if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) {
|
||||
@@ -1780,8 +1782,10 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
|
||||
if (!archs.empty() && !lang.empty() &&
|
||||
(lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
|
||||
for (std::string const& arch : archs) {
|
||||
flags += " -arch ";
|
||||
flags += arch;
|
||||
if (filterArch.empty() || filterArch == arch) {
|
||||
flags += " -arch ";
|
||||
flags += arch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1804,10 +1808,12 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
|
||||
if (arch_sysroots[i].empty()) {
|
||||
continue;
|
||||
}
|
||||
flags += " -Xarch_" + archs[i] + " ";
|
||||
// Combine sysroot flag and path to work with -Xarch
|
||||
std::string arch_sysroot = sysrootFlag + arch_sysroots[i];
|
||||
flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
|
||||
if (filterArch.empty() || filterArch == archs[i]) {
|
||||
flags += " -Xarch_" + archs[i] + " ";
|
||||
// Combine sysroot flag and path to work with -Xarch
|
||||
std::string arch_sysroot = sysrootFlag + arch_sysroots[i];
|
||||
flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
|
||||
}
|
||||
}
|
||||
} else if (sysroot && *sysroot) {
|
||||
flags += " ";
|
||||
@@ -2446,146 +2452,174 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string pchSource = target->GetPchSource(config, lang);
|
||||
const std::string pchHeader = target->GetPchHeader(config, lang);
|
||||
|
||||
if (pchSource.empty() || pchHeader.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string pchExtension =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
if (pchExtension.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* pchReuseFrom =
|
||||
target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
|
||||
auto pch_sf = this->Makefile->GetOrCreateSource(
|
||||
pchSource, false, cmSourceFileLocationKind::Known);
|
||||
|
||||
std::vector<std::string> architectures;
|
||||
if (!this->GetGlobalGenerator()->IsXcode()) {
|
||||
if (!pchReuseFrom) {
|
||||
target->AddSource(pchSource, true);
|
||||
}
|
||||
|
||||
const std::string pchFile = target->GetPchFile(config, lang);
|
||||
|
||||
// Exclude the pch files from linking
|
||||
if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
|
||||
if (!pchReuseFrom) {
|
||||
pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
|
||||
} else {
|
||||
auto reuseTarget =
|
||||
this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
|
||||
|
||||
if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
|
||||
|
||||
const std::string pdb_prefix =
|
||||
this->GetGlobalGenerator()->IsMultiConfig()
|
||||
? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
|
||||
: "";
|
||||
|
||||
const std::string target_compile_pdb_dir = cmStrCat(
|
||||
target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
|
||||
target->GetName(), ".dir/");
|
||||
|
||||
const std::string copy_script =
|
||||
cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
|
||||
cmGeneratedFileStream file(copy_script);
|
||||
|
||||
file << "# CMake generated file\n";
|
||||
for (auto extension : { ".pdb", ".idb" }) {
|
||||
const std::string from_file =
|
||||
cmStrCat(reuseTarget->GetLocalGenerator()
|
||||
->GetCurrentBinaryDirectory(),
|
||||
"/", pchReuseFrom, ".dir/${PDB_PREFIX}",
|
||||
pchReuseFrom, extension);
|
||||
|
||||
const std::string to_dir = cmStrCat(
|
||||
target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
|
||||
"/", target->GetName(), ".dir/${PDB_PREFIX}");
|
||||
|
||||
const std::string to_file =
|
||||
cmStrCat(to_dir, pchReuseFrom, extension);
|
||||
|
||||
std::string dest_file = to_file;
|
||||
|
||||
const std::string prefix = target->GetSafeProperty("PREFIX");
|
||||
if (!prefix.empty()) {
|
||||
dest_file =
|
||||
cmStrCat(to_dir, prefix, pchReuseFrom, extension);
|
||||
}
|
||||
|
||||
file << "if (EXISTS \"" << from_file << "\" AND \""
|
||||
<< from_file << "\" IS_NEWER_THAN \"" << dest_file
|
||||
<< "\")\n";
|
||||
file << " file(COPY \"" << from_file << "\""
|
||||
<< " DESTINATION \"" << to_dir << "\")\n";
|
||||
if (!prefix.empty()) {
|
||||
file << " file(REMOVE \"" << dest_file << "\")\n";
|
||||
file << " file(RENAME \"" << to_file << "\" \"" << dest_file
|
||||
<< "\")\n";
|
||||
}
|
||||
file << "endif()\n";
|
||||
}
|
||||
|
||||
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
|
||||
{ cmSystemTools::GetCMakeCommand(),
|
||||
cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P", copy_script });
|
||||
|
||||
const std::string no_main_dependency;
|
||||
const std::vector<std::string> no_deps;
|
||||
const char* no_message = "";
|
||||
const char* no_current_dir = nullptr;
|
||||
std::vector<std::string> no_byproducts;
|
||||
|
||||
std::vector<std::string> outputs;
|
||||
outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
|
||||
pchReuseFrom, ".pdb"));
|
||||
|
||||
if (this->GetGlobalGenerator()->IsVisualStudio()) {
|
||||
this->AddCustomCommandToTarget(
|
||||
target->GetName(), outputs, no_deps, commandLines,
|
||||
cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
|
||||
} else {
|
||||
cmImplicitDependsList no_implicit_depends;
|
||||
cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
|
||||
outputs, no_byproducts, no_deps, no_main_dependency,
|
||||
no_implicit_depends, commandLines, no_message,
|
||||
no_current_dir);
|
||||
|
||||
if (copy_rule) {
|
||||
target->AddSource(copy_rule->ResolveFullPath());
|
||||
}
|
||||
}
|
||||
|
||||
target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
|
||||
target_compile_pdb_dir);
|
||||
}
|
||||
|
||||
std::string pchSourceObj =
|
||||
reuseTarget->GetPchFileObject(config, lang);
|
||||
|
||||
// Link to the pch object file
|
||||
target->Target->AppendProperty(
|
||||
"LINK_FLAGS",
|
||||
cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL)),
|
||||
true);
|
||||
target->GetAppleArchs(config, architectures);
|
||||
}
|
||||
if (architectures.empty()) {
|
||||
architectures.emplace_back();
|
||||
} else {
|
||||
std::string useMultiArchPch;
|
||||
for (const std::string& arch : architectures) {
|
||||
const std::string pchHeader =
|
||||
target->GetPchHeader(config, lang, arch);
|
||||
if (!pchHeader.empty()) {
|
||||
useMultiArchPch = cmStrCat(useMultiArchPch, ";-Xarch_", arch,
|
||||
";-include", pchHeader);
|
||||
}
|
||||
} else {
|
||||
pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
|
||||
}
|
||||
|
||||
// Add pchHeader to source files, which will
|
||||
// be grouped as "Precompile Header File"
|
||||
auto pchHeader_sf = this->Makefile->GetOrCreateSource(
|
||||
pchHeader, false, cmSourceFileLocationKind::Known);
|
||||
std::string err;
|
||||
pchHeader_sf->ResolveFullPath(&err);
|
||||
target->AddSource(pchHeader);
|
||||
if (!useMultiArchPch.empty()) {
|
||||
target->Target->SetProperty(
|
||||
cmStrCat(lang, "_COMPILE_OPTIONS_USE_PCH"), useMultiArchPch);
|
||||
}
|
||||
}
|
||||
|
||||
for (const std::string& arch : architectures) {
|
||||
const std::string pchSource = target->GetPchSource(config, lang, arch);
|
||||
const std::string pchHeader = target->GetPchHeader(config, lang, arch);
|
||||
|
||||
if (pchSource.empty() || pchHeader.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string pchExtension =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
if (pchExtension.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* pchReuseFrom =
|
||||
target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
|
||||
auto pch_sf = this->Makefile->GetOrCreateSource(
|
||||
pchSource, false, cmSourceFileLocationKind::Known);
|
||||
|
||||
if (!this->GetGlobalGenerator()->IsXcode()) {
|
||||
if (!pchReuseFrom) {
|
||||
target->AddSource(pchSource, true);
|
||||
}
|
||||
|
||||
const std::string pchFile = target->GetPchFile(config, lang, arch);
|
||||
|
||||
// Exclude the pch files from linking
|
||||
if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
|
||||
if (!pchReuseFrom) {
|
||||
pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
|
||||
} else {
|
||||
auto reuseTarget =
|
||||
this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
|
||||
|
||||
if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
|
||||
|
||||
const std::string pdb_prefix =
|
||||
this->GetGlobalGenerator()->IsMultiConfig()
|
||||
? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
|
||||
: "";
|
||||
|
||||
const std::string target_compile_pdb_dir = cmStrCat(
|
||||
target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
|
||||
"/", target->GetName(), ".dir/");
|
||||
|
||||
const std::string copy_script =
|
||||
cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
|
||||
cmGeneratedFileStream file(copy_script);
|
||||
|
||||
file << "# CMake generated file\n";
|
||||
for (auto extension : { ".pdb", ".idb" }) {
|
||||
const std::string from_file =
|
||||
cmStrCat(reuseTarget->GetLocalGenerator()
|
||||
->GetCurrentBinaryDirectory(),
|
||||
"/", pchReuseFrom, ".dir/${PDB_PREFIX}",
|
||||
pchReuseFrom, extension);
|
||||
|
||||
const std::string to_dir = cmStrCat(
|
||||
target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
|
||||
"/", target->GetName(), ".dir/${PDB_PREFIX}");
|
||||
|
||||
const std::string to_file =
|
||||
cmStrCat(to_dir, pchReuseFrom, extension);
|
||||
|
||||
std::string dest_file = to_file;
|
||||
|
||||
const std::string prefix = target->GetSafeProperty("PREFIX");
|
||||
if (!prefix.empty()) {
|
||||
dest_file =
|
||||
cmStrCat(to_dir, prefix, pchReuseFrom, extension);
|
||||
}
|
||||
|
||||
file << "if (EXISTS \"" << from_file << "\" AND \""
|
||||
<< from_file << "\" IS_NEWER_THAN \"" << dest_file
|
||||
<< "\")\n";
|
||||
file << " file(COPY \"" << from_file << "\""
|
||||
<< " DESTINATION \"" << to_dir << "\")\n";
|
||||
if (!prefix.empty()) {
|
||||
file << " file(REMOVE \"" << dest_file << "\")\n";
|
||||
file << " file(RENAME \"" << to_file << "\" \""
|
||||
<< dest_file << "\")\n";
|
||||
}
|
||||
file << "endif()\n";
|
||||
}
|
||||
|
||||
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
|
||||
{ cmSystemTools::GetCMakeCommand(),
|
||||
cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P",
|
||||
copy_script });
|
||||
|
||||
const std::string no_main_dependency;
|
||||
const std::vector<std::string> no_deps;
|
||||
const char* no_message = "";
|
||||
const char* no_current_dir = nullptr;
|
||||
std::vector<std::string> no_byproducts;
|
||||
|
||||
std::vector<std::string> outputs;
|
||||
outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
|
||||
pchReuseFrom, ".pdb"));
|
||||
|
||||
if (this->GetGlobalGenerator()->IsVisualStudio()) {
|
||||
this->AddCustomCommandToTarget(
|
||||
target->GetName(), outputs, no_deps, commandLines,
|
||||
cmCustomCommandType::PRE_BUILD, no_message,
|
||||
no_current_dir);
|
||||
} else {
|
||||
cmImplicitDependsList no_implicit_depends;
|
||||
cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
|
||||
outputs, no_byproducts, no_deps, no_main_dependency,
|
||||
no_implicit_depends, commandLines, no_message,
|
||||
no_current_dir);
|
||||
|
||||
if (copy_rule) {
|
||||
target->AddSource(copy_rule->ResolveFullPath());
|
||||
}
|
||||
}
|
||||
|
||||
target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
|
||||
target_compile_pdb_dir);
|
||||
}
|
||||
|
||||
std::string pchSourceObj =
|
||||
reuseTarget->GetPchFileObject(config, lang, arch);
|
||||
|
||||
// Link to the pch object file
|
||||
target->Target->AppendProperty(
|
||||
"LINK_FLAGS",
|
||||
cmStrCat(" ",
|
||||
this->ConvertToOutputFormat(pchSourceObj, SHELL)),
|
||||
true);
|
||||
}
|
||||
} else {
|
||||
pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
|
||||
}
|
||||
|
||||
// Add pchHeader to source files, which will
|
||||
// be grouped as "Precompile Header File"
|
||||
auto pchHeader_sf = this->Makefile->GetOrCreateSource(
|
||||
pchHeader, false, cmSourceFileLocationKind::Known);
|
||||
std::string err;
|
||||
pchHeader_sf->ResolveFullPath(&err);
|
||||
target->AddSource(pchHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,8 +105,8 @@ public:
|
||||
|
||||
void AddArchitectureFlags(std::string& flags,
|
||||
cmGeneratorTarget const* target,
|
||||
const std::string& lang,
|
||||
const std::string& config);
|
||||
const std::string& lang, const std::string& config,
|
||||
const std::string& filterArch = std::string());
|
||||
|
||||
void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
|
||||
const std::string& lang, const std::string& config);
|
||||
@@ -435,10 +435,11 @@ public:
|
||||
std::string const& lang) const;
|
||||
void GetTargetCompileFlags(cmGeneratorTarget* target,
|
||||
std::string const& config,
|
||||
std::string const& lang, std::string& flags);
|
||||
std::vector<BT<std::string>> GetTargetCompileFlags(cmGeneratorTarget* target,
|
||||
std::string const& config,
|
||||
std::string const& lang);
|
||||
std::string const& lang, std::string& flags,
|
||||
std::string const& arch = std::string());
|
||||
std::vector<BT<std::string>> GetTargetCompileFlags(
|
||||
cmGeneratorTarget* target, std::string const& config,
|
||||
std::string const& lang, std::string const& arch = std::string());
|
||||
|
||||
std::string GetFrameworkFlags(std::string const& l,
|
||||
std::string const& config,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include <cm/memory>
|
||||
@@ -341,16 +342,25 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
|
||||
}
|
||||
|
||||
for (std::string const& language : languages) {
|
||||
std::string flags = this->GetFlags(language, this->GetConfigName());
|
||||
std::string defines = this->GetDefines(language, this->GetConfigName());
|
||||
std::string includes = this->GetIncludes(language, this->GetConfigName());
|
||||
// Escape comment characters so they do not terminate assignment.
|
||||
cmSystemTools::ReplaceString(flags, "#", "\\#");
|
||||
cmSystemTools::ReplaceString(defines, "#", "\\#");
|
||||
cmSystemTools::ReplaceString(includes, "#", "\\#");
|
||||
*this->FlagFileStream << language << "_FLAGS = " << flags << "\n\n";
|
||||
*this->FlagFileStream << language << "_DEFINES = " << defines << "\n\n";
|
||||
*this->FlagFileStream << language << "_INCLUDES = " << includes << "\n\n";
|
||||
|
||||
std::vector<std::string> architectures;
|
||||
this->GeneratorTarget->GetAppleArchs(this->GetConfigName(), architectures);
|
||||
architectures.emplace_back();
|
||||
|
||||
for (const std::string& arch : architectures) {
|
||||
std::string flags =
|
||||
this->GetFlags(language, this->GetConfigName(), arch);
|
||||
cmSystemTools::ReplaceString(flags, "#", "\\#");
|
||||
*this->FlagFileStream << language << "_FLAGS" << arch << " = " << flags
|
||||
<< "\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,17 +473,37 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
std::string configUpper = cmSystemTools::UpperCase(config);
|
||||
|
||||
// Add precompile headers dependencies
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(config, lang);
|
||||
if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
std::string const& pchHeader =
|
||||
this->GeneratorTarget->GetPchHeader(config, lang);
|
||||
depends.push_back(pchHeader);
|
||||
if (source.GetFullPath() != pchSource) {
|
||||
depends.push_back(this->GeneratorTarget->GetPchFile(config, lang));
|
||||
std::vector<std::string> architectures;
|
||||
this->GeneratorTarget->GetAppleArchs(config, architectures);
|
||||
if (architectures.empty()) {
|
||||
architectures.emplace_back();
|
||||
}
|
||||
|
||||
std::string filterArch;
|
||||
std::unordered_map<std::string, std::string> pchSources;
|
||||
for (const std::string& arch : architectures) {
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(config, lang, arch);
|
||||
if (pchSource == source.GetFullPath()) {
|
||||
filterArch = arch;
|
||||
}
|
||||
if (!pchSource.empty()) {
|
||||
pchSources.insert(std::make_pair(pchSource, arch));
|
||||
}
|
||||
}
|
||||
|
||||
if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
for (const std::string& arch : architectures) {
|
||||
std::string const& pchHeader =
|
||||
this->GeneratorTarget->GetPchHeader(config, lang, arch);
|
||||
depends.push_back(pchHeader);
|
||||
if (pchSources.find(source.GetFullPath()) == pchSources.end()) {
|
||||
depends.push_back(
|
||||
this->GeneratorTarget->GetPchFile(config, lang, arch));
|
||||
}
|
||||
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
|
||||
objFullPath, pchHeader);
|
||||
}
|
||||
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
|
||||
objFullPath, pchHeader);
|
||||
}
|
||||
|
||||
std::string relativeObj =
|
||||
@@ -484,7 +514,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
std::string flags;
|
||||
|
||||
// Add language-specific flags.
|
||||
std::string langFlags = cmStrCat("$(", lang, "_FLAGS)");
|
||||
std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
|
||||
this->LocalGenerator->AppendFlags(flags, langFlags);
|
||||
|
||||
cmGeneratorExpressionInterpreter genexInterpreter(
|
||||
@@ -517,11 +547,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
|
||||
}
|
||||
|
||||
// Add precompile headers compile options.
|
||||
if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
std::string pchOptions;
|
||||
if (source.GetFullPath() == pchSource) {
|
||||
pchOptions =
|
||||
this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
|
||||
auto pchIt = pchSources.find(source.GetFullPath());
|
||||
if (pchIt != pchSources.end()) {
|
||||
pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
|
||||
config, lang, pchIt->second);
|
||||
} else {
|
||||
pchOptions =
|
||||
this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
#include <cm/memory>
|
||||
@@ -157,7 +159,26 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
cmSourceFile const* source, const std::string& language,
|
||||
const std::string& config)
|
||||
{
|
||||
std::string flags = this->GetFlags(language, config);
|
||||
std::vector<std::string> architectures;
|
||||
std::unordered_map<std::string, std::string> pchSources;
|
||||
this->GeneratorTarget->GetAppleArchs(config, architectures);
|
||||
if (architectures.empty()) {
|
||||
architectures.emplace_back();
|
||||
}
|
||||
|
||||
std::string filterArch;
|
||||
for (const std::string& arch : architectures) {
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(config, language, arch);
|
||||
if (pchSource == source->GetFullPath()) {
|
||||
filterArch = arch;
|
||||
}
|
||||
if (!pchSource.empty()) {
|
||||
pchSources.insert(std::make_pair(pchSource, arch));
|
||||
}
|
||||
}
|
||||
|
||||
std::string flags = this->GetFlags(language, config, filterArch);
|
||||
|
||||
// Add Fortran format flags.
|
||||
if (language == "Fortran") {
|
||||
@@ -181,14 +202,12 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
|
||||
}
|
||||
|
||||
// Add precompile headers compile options.
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(config, language);
|
||||
|
||||
if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
std::string pchOptions;
|
||||
if (source->GetFullPath() == pchSource) {
|
||||
pchOptions =
|
||||
this->GeneratorTarget->GetPchCreateCompileOptions(config, language);
|
||||
auto pchIt = pchSources.find(source->GetFullPath());
|
||||
if (pchIt != pchSources.end()) {
|
||||
pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
|
||||
config, language, pchIt->second);
|
||||
} else {
|
||||
pchOptions =
|
||||
this->GeneratorTarget->GetPchUseCompileOptions(config, language);
|
||||
@@ -1050,12 +1069,30 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
// Add precompile headers dependencies
|
||||
std::vector<std::string> depList;
|
||||
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(config, language);
|
||||
if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
depList.push_back(this->GeneratorTarget->GetPchHeader(config, language));
|
||||
if (source->GetFullPath() != pchSource) {
|
||||
depList.push_back(this->GeneratorTarget->GetPchFile(config, language));
|
||||
std::vector<std::string> architectures;
|
||||
this->GeneratorTarget->GetAppleArchs(config, architectures);
|
||||
if (architectures.empty()) {
|
||||
architectures.emplace_back();
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> pchSources;
|
||||
for (const std::string& arch : architectures) {
|
||||
const std::string pchSource =
|
||||
this->GeneratorTarget->GetPchSource(config, language, arch);
|
||||
|
||||
if (!pchSource.empty()) {
|
||||
pchSources.insert(pchSource);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
for (const std::string& arch : architectures) {
|
||||
depList.push_back(
|
||||
this->GeneratorTarget->GetPchHeader(config, language, arch));
|
||||
if (pchSources.find(source->GetFullPath()) == pchSources.end()) {
|
||||
depList.push_back(
|
||||
this->GeneratorTarget->GetPchFile(config, language, arch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,8 +1245,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
|
||||
vars);
|
||||
|
||||
if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
if (source->GetFullPath() == pchSource) {
|
||||
if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
|
||||
auto pchIt = pchSources.find(source->GetFullPath());
|
||||
if (pchIt != pchSources.end()) {
|
||||
this->addPoolNinjaVariable("JOB_POOL_PRECOMPILE_HEADER",
|
||||
this->GetGeneratorTarget(), vars);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user