Commit 856e181a authored by Cristian Adam's avatar Cristian Adam Committed by Brad King
Browse files

PCH: Add genex support for REUSE_FROM signature

Fixes: #20523
parent d4d67810
Pipeline #213874 waiting for manual action with stages
in 8 minutes and 14 seconds
......@@ -3885,8 +3885,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
return std::string();
}
const cmGeneratorTarget* generatorTarget = this;
cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
cmProp pchReuseFrom = generatorTarget->GetPchReuseFrom(config);
const auto inserted =
this->PchHeaders.insert(std::make_pair(language + config + arch, ""));
......@@ -3998,8 +3997,7 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
std::string& filename = inserted.first->second;
const cmGeneratorTarget* generatorTarget = this;
cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
cmProp pchReuseFrom = generatorTarget->GetPchReuseFrom(config);
if (pchReuseFrom) {
generatorTarget =
this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
......@@ -4096,8 +4094,7 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
};
cmGeneratorTarget* generatorTarget = this;
cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
cmProp pchReuseFrom = generatorTarget->GetPchReuseFrom(config);
if (pchReuseFrom) {
generatorTarget =
this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
......@@ -4190,6 +4187,55 @@ std::string cmGeneratorTarget::GetPchUseCompileOptions(
return inserted.first->second;
}
cmProp cmGeneratorTarget::GetPchReuseFrom(const std::string& config) const
{
cmProp value = this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
if (!value) {
return value;
}
const auto inserted = this->PchReuseFrom.insert(std::make_pair(config, ""));
if (inserted.second) {
std::string& pchReuseFrom = inserted.first->second;
if (pchReuseFrom.empty()) {
std::string evaluatedValue =
cmGeneratorExpression::Evaluate(*value, this->LocalGenerator, config);
if (evaluatedValue.empty()) {
return nullptr;
}
auto* reusedTarget =
this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
evaluatedValue);
if (!reusedTarget) {
const std::string e = cmStrCat(
"PRECOMPILE_HEADERS_REUSE_FROM set with non existing target: ",
evaluatedValue);
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
return nullptr;
}
pchReuseFrom = cmGeneratorExpression::Evaluate(
reusedTarget->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM"),
this->LocalGenerator, config);
if (pchReuseFrom.empty()) {
pchReuseFrom = evaluatedValue;
}
reusedTarget->SetProperty("COMPILE_PDB_NAME", pchReuseFrom);
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
cmStrCat(pchReuseFrom, ".dir/"));
cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
this->Target->SetProperty("COMPILE_PDB_NAME", cmToCStr(tmp));
this->Target->AddUtility(pchReuseFrom, false, this->Makefile);
}
}
return &inserted.first->second;
}
void cmGeneratorTarget::AddSourceFileToUnityBatch(
const std::string& sourceFilename)
{
......
......@@ -530,6 +530,7 @@ public:
std::string GetPchUseCompileOptions(const std::string& config,
const std::string& language,
const std::string& arch = std::string());
cmProp GetPchReuseFrom(const std::string& config) const;
void AddSourceFileToUnityBatch(const std::string& sourceFilename);
bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const;
......@@ -1015,6 +1016,7 @@ private:
mutable std::map<std::string, std::string> PchFiles;
mutable std::map<std::string, std::string> PchCreateCompileOptions;
mutable std::map<std::string, std::string> PchUseCompileOptions;
mutable std::map<std::string, std::string> PchReuseFrom;
std::unordered_set<std::string> UnityBatchedSourceFiles;
......
......@@ -357,40 +357,6 @@ bool cmGlobalGenerator::CheckTargetsForType() const
return failed;
}
bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
{
if (!this->GetLanguageEnabled("C") && !this->GetLanguageEnabled("CXX")) {
return false;
}
bool failed = false;
for (const auto& generator : this->LocalGenerators) {
for (const auto& target : generator->GetGeneratorTargets()) {
if (!target->CanCompileSources() ||
cmIsOn(target->GetProperty("ghs_integrity_app"))) {
continue;
}
std::string const& reuseFrom =
target->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM");
std::string const& compilePdb =
target->GetSafeProperty("COMPILE_PDB_NAME");
if (!reuseFrom.empty() && reuseFrom != compilePdb) {
const std::string e = cmStrCat(
"PRECOMPILE_HEADERS_REUSE_FROM property is set on target (\"",
target->GetName(),
"\"). Reusable precompile headers requires the COMPILE_PDB_NAME"
" property to have the value \"",
reuseFrom, "\"\n");
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
target->GetBacktrace());
failed = true;
}
}
}
return failed;
}
bool cmGlobalGenerator::IsExportedTargetsFile(
const std::string& filename) const
{
......@@ -1486,10 +1452,6 @@ bool cmGlobalGenerator::Compute()
return false;
}
if (this->CheckTargetsForPchCompilePdb()) {
return false;
}
for (const auto& localGen : this->LocalGenerators) {
localGen->ComputeHomeRelativeOutputPath();
}
......
......@@ -682,7 +682,6 @@ private:
bool CheckTargetsForMissingSources() const;
bool CheckTargetsForType() const;
bool CheckTargetsForPchCompilePdb() const;
void CreateLocalGenerators();
......
......@@ -2547,8 +2547,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
continue;
}
cmProp ReuseFrom =
target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
cmProp ReuseFrom = target->GetPchReuseFrom(config);
auto* pch_sf = this->Makefile->GetOrCreateSource(
pchSource, false, cmSourceFileLocationKind::Known);
......
......@@ -1327,30 +1327,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
auto* reusedTarget = this->impl->Makefile->GetCMakeInstance()
->GetGlobalGenerator()
->FindTarget(value);
if (!reusedTarget) {
const std::string e(
"PRECOMPILE_HEADERS_REUSE_FROM set with non existing target");
this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
return;
}
std::string reusedFrom = reusedTarget->GetSafeProperty(prop);
if (reusedFrom.empty()) {
reusedFrom = value;
}
this->impl->Properties.SetProperty(prop, reusedFrom.c_str());
reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom);
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
cmStrCat(reusedFrom, ".dir/"));
cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
this->SetProperty("COMPILE_PDB_NAME", cmToCStr(tmp));
this->AddUtility(reusedFrom, false, this->impl->Makefile);
this->impl->Properties.SetProperty(prop, value);
} else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
prop == propCUDA_STANDARD || prop == propOBJC_STANDARD ||
prop == propOBJCXX_STANDARD) {
......
(CMake Error:
Error evaluating generator expression:
\$<NOTGENEX>
Expression did not evaluate to a known generator expression)
cmake_minimum_required(VERSION 3.15)
project(PchReuseFromBadGenex C)
if(CMAKE_C_COMPILE_OPTIONS_USE_PCH)
add_definitions(-DHAVE_PCH_SUPPORT)
endif()
# Add this before the target from which we will reuse the PCH
# to test that generators can handle reversed ordering.
add_library(foo foo.c)
target_include_directories(foo PUBLIC include)
add_library(empty empty.c)
target_precompile_headers(empty PRIVATE
<stdio.h>
<string.h>
)
target_include_directories(empty PUBLIC include)
target_precompile_headers(foo REUSE_FROM $<NOTGENEX>)
cmake_minimum_required(VERSION 3.15)
project(PchReuseFromGenex C)
if(CMAKE_C_COMPILE_OPTIONS_USE_PCH)
add_definitions(-DHAVE_PCH_SUPPORT)
endif()
# Add this before the target from which we will reuse the PCH
# to test that generators can handle reversed ordering.
add_library(foo foo.c)
target_include_directories(foo PUBLIC include)
add_library(empty empty.c)
target_precompile_headers(empty PRIVATE
<stdio.h>
<string.h>
)
target_include_directories(empty PUBLIC include)
target_precompile_headers(foo REUSE_FROM $<$<TARGET_EXISTS:empty>:empty>)
# should not cause problems if configured multiple times
target_precompile_headers(foo REUSE_FROM $<$<TARGET_EXISTS:empty>:empty>)
add_executable(foobar foobar.c)
target_link_libraries(foobar foo )
set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo)
enable_testing()
add_test(NAME foobar COMMAND foobar)
......@@ -15,6 +15,8 @@ run_test(PchInterface)
run_cmake(PchPrologueEpilogue)
run_test(SkipPrecompileHeaders)
run_test(PchReuseFrom)
run_test(PchReuseFromGenex)
run_cmake(PchReuseFromBadGenex)
run_test(PchReuseFromPrefixed)
run_test(PchReuseFromSubdir)
run_cmake(PchMultilanguage)
......
......@@ -36,7 +36,6 @@ run_cmake(VsPackageReferences)
run_cmake(VsDpiAware)
run_cmake(VsDpiAwareBadParam)
run_cmake(VsPrecompileHeaders)
run_cmake(VsPrecompileHeadersReuseFromCompilePDBName)
run_cmake(VsDeployEnabled)
run_cmake(VsSettings)
run_cmake(VsSourceSettingsTool)
......
project(VsPrecompileHeadersReuseFromCompilePDBName CXX)
add_library(a SHARED empty.cxx)
target_precompile_headers(a PRIVATE <windows.h>)
add_library(b SHARED empty.cxx)
target_precompile_headers(b REUSE_FROM a)
set_target_properties(b PROPERTIES COMPILE_PDB_NAME b)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment