mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 05:40:54 -06:00
Merge topic 'pchreuse-refactor'
11ee18b758ci: extend msvc_v71_nmake `RunCMake.PrecompileHeaders` test timeout1c91fadbe8Tests/RunCMake/PrecompileHeaders: support extended timeout42f2867b3bpchreuse: defer dependency addition until generation timef9bc615d9apchreuse: ban PCH reuse from targets which disable PCHf78f592b78pchreuse: defer target existence enforcement to generation time3ef773490dpchreuse: defer PCH consistency checks to generation time1d701491a2pchreuse: always ask the PCH reuse target for PDB information6e7da8aa95cmGeneratorTarget: factor out reuse target computation ... Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Acked-by: alcroito <alexandru.croitor@qt.io> Acked-by: Vincent X <gulackeg@gmail.com> Merge-request: !10887
This commit is contained in:
@@ -1 +1,3 @@
|
||||
set(CMake_TEST_PrecompileHeaders_TIMEOUT 1000 CACHE STRING "")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_common.cmake")
|
||||
|
||||
@@ -9,6 +9,9 @@ compiler while building source files.
|
||||
This property specifies the base name for the debug symbols file.
|
||||
If not set, the default is unspecified.
|
||||
|
||||
If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
|
||||
is ignored and the reusage target's value of this property is used instead.
|
||||
|
||||
.. versionadded:: 4.1
|
||||
|
||||
Contents of ``COMPILE_PDB_NAME`` may use
|
||||
|
||||
@@ -13,5 +13,8 @@ This is the configuration-specific version of :prop_tgt:`COMPILE_PDB_NAME`.
|
||||
Contents of ``COMPILE_PDB_NAME_<CONFIG>`` may use
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
|
||||
is ignored and the reusage target's value of this property is used instead.
|
||||
|
||||
.. |PDB_XXX| replace:: :prop_tgt:`PDB_NAME_<CONFIG>`
|
||||
.. include:: include/COMPILE_PDB_NOTE.rst
|
||||
|
||||
@@ -21,5 +21,8 @@ This property is initialized by the value of the
|
||||
:variable:`CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY` variable if it is
|
||||
set when a target is created.
|
||||
|
||||
If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
|
||||
is ignored and the reusage target's value of this property is used instead.
|
||||
|
||||
.. |PDB_XXX| replace:: :prop_tgt:`PDB_OUTPUT_DIRECTORY`
|
||||
.. include:: include/COMPILE_PDB_NOTE.rst
|
||||
|
||||
@@ -20,5 +20,8 @@ if it is set when a target is created.
|
||||
Contents of ``COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>`` may use
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||
|
||||
If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
|
||||
is ignored and the reusage target's value of this property is used instead.
|
||||
|
||||
.. |PDB_XXX| replace:: :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`
|
||||
.. include:: include/COMPILE_PDB_NOTE.rst
|
||||
|
||||
@@ -1008,6 +1008,10 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
|
||||
cmLinkItem(i.Value.first, i.Value.second, i.Backtrace));
|
||||
}
|
||||
}
|
||||
if (cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget()) {
|
||||
this->UtilityItems.insert(
|
||||
cmLinkItem(reuseTarget, false, cmListFileBacktrace()));
|
||||
}
|
||||
}
|
||||
return this->UtilityItems;
|
||||
}
|
||||
@@ -1269,6 +1273,12 @@ bool cmGeneratorTarget::GetPropertyAsBool(std::string const& prop) const
|
||||
std::string cmGeneratorTarget::GetCompilePDBName(
|
||||
std::string const& config) const
|
||||
{
|
||||
if (cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget()) {
|
||||
if (reuseTarget != this) {
|
||||
return reuseTarget->GetCompilePDBName(config);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a per-configuration output directory target property.
|
||||
std::string configUpper = cmSystemTools::UpperCase(config);
|
||||
std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper);
|
||||
@@ -1290,6 +1300,14 @@ std::string cmGeneratorTarget::GetCompilePDBName(
|
||||
return components.prefix + pdbName + ".pdb";
|
||||
}
|
||||
|
||||
// If the target is PCH-reused, we need a stable name for the PDB file so
|
||||
// that reusing targets can construct a stable name for it.
|
||||
if (this->PchReused) {
|
||||
NameComponents const& components = GetFullNameInternalComponents(
|
||||
config, cmStateEnums::RuntimeBinaryArtifact);
|
||||
return cmStrCat(components.prefix, this->GetName(), ".pdb");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -2799,6 +2817,122 @@ std::string cmGeneratorTarget::GetClangTidyExportFixesDirectory(
|
||||
return cmSystemTools::CollapseFullPath(path);
|
||||
}
|
||||
|
||||
struct CycleWatcher
|
||||
{
|
||||
CycleWatcher(bool& flag)
|
||||
: Flag(flag)
|
||||
{
|
||||
this->Flag = true;
|
||||
}
|
||||
~CycleWatcher() { this->Flag = false; }
|
||||
bool& Flag;
|
||||
};
|
||||
|
||||
cmGeneratorTarget const* cmGeneratorTarget::GetPchReuseTarget() const
|
||||
{
|
||||
if (this->ComputingPchReuse) {
|
||||
// TODO: Get the full cycle.
|
||||
if (!this->PchReuseCycleDetected) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Circular PCH reuse target involving '", this->GetName(),
|
||||
'\''));
|
||||
}
|
||||
this->PchReuseCycleDetected = true;
|
||||
return nullptr;
|
||||
}
|
||||
CycleWatcher watch(this->ComputingPchReuse);
|
||||
(void)watch;
|
||||
cmValue pchReuseFrom = this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
if (!pchReuseFrom) {
|
||||
return nullptr;
|
||||
}
|
||||
cmGeneratorTarget const* generatorTarget =
|
||||
this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
|
||||
if (!generatorTarget) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
|
||||
R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property does not exist.)"));
|
||||
}
|
||||
if (this->GetProperty("PRECOMPILE_HEADERS").IsOn()) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("PRECOMPILE_HEADERS property is already set on target (\"",
|
||||
this->GetName(), "\")\n"));
|
||||
}
|
||||
|
||||
if (generatorTarget) {
|
||||
if (generatorTarget->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
|
||||
R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property has set "DISABLE_PRECOMPILE_HEADERS".)"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto const* recurseReuseTarget =
|
||||
generatorTarget->GetPchReuseTarget()) {
|
||||
return recurseReuseTarget;
|
||||
}
|
||||
}
|
||||
return generatorTarget;
|
||||
}
|
||||
|
||||
cmGeneratorTarget* cmGeneratorTarget::GetPchReuseTarget()
|
||||
{
|
||||
if (this->ComputingPchReuse) {
|
||||
// TODO: Get the full cycle.
|
||||
if (!this->PchReuseCycleDetected) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("Circular PCH reuse target involving '", this->GetName(),
|
||||
'\''));
|
||||
}
|
||||
this->PchReuseCycleDetected = true;
|
||||
return nullptr;
|
||||
}
|
||||
CycleWatcher watch(this->ComputingPchReuse);
|
||||
(void)watch;
|
||||
cmValue pchReuseFrom = this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
if (!pchReuseFrom) {
|
||||
return nullptr;
|
||||
}
|
||||
cmGeneratorTarget* generatorTarget =
|
||||
this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
|
||||
if (!generatorTarget) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
|
||||
R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property does not exist.)"));
|
||||
}
|
||||
if (this->GetProperty("PRECOMPILE_HEADERS").IsOn()) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("PRECOMPILE_HEADERS property is already set on target (\"",
|
||||
this->GetName(), "\")\n"));
|
||||
}
|
||||
|
||||
if (generatorTarget) {
|
||||
if (generatorTarget->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
|
||||
R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property has set "DISABLE_PRECOMPILE_HEADERS".)"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto* recurseReuseTarget = generatorTarget->GetPchReuseTarget()) {
|
||||
return recurseReuseTarget;
|
||||
}
|
||||
}
|
||||
return generatorTarget;
|
||||
}
|
||||
|
||||
std::vector<std::string> cmGeneratorTarget::GetPchArchs(
|
||||
std::string const& config, std::string const& lang) const
|
||||
{
|
||||
@@ -2826,24 +2960,22 @@ std::string cmGeneratorTarget::GetPchHeader(std::string const& config,
|
||||
return std::string();
|
||||
}
|
||||
cmGeneratorTarget const* generatorTarget = this;
|
||||
cmValue pchReuseFrom =
|
||||
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget();
|
||||
bool const haveReuseTarget = reuseTarget && reuseTarget != this;
|
||||
if (reuseTarget) {
|
||||
generatorTarget = reuseTarget;
|
||||
}
|
||||
|
||||
auto const inserted =
|
||||
this->PchHeaders.insert(std::make_pair(language + config + arch, ""));
|
||||
if (inserted.second) {
|
||||
std::vector<BT<std::string>> const headers =
|
||||
this->GetPrecompileHeaders(config, language);
|
||||
if (headers.empty() && !pchReuseFrom) {
|
||||
if (headers.empty() && !haveReuseTarget) {
|
||||
return std::string();
|
||||
}
|
||||
std::string& filename = inserted.first->second;
|
||||
|
||||
if (pchReuseFrom) {
|
||||
generatorTarget =
|
||||
this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> const languageToExtension = {
|
||||
{ "C", ".h" },
|
||||
{ "CXX", ".hxx" },
|
||||
@@ -2862,7 +2994,7 @@ std::string cmGeneratorTarget::GetPchHeader(std::string const& config,
|
||||
languageToExtension.at(language));
|
||||
|
||||
std::string const filename_tmp = cmStrCat(filename, ".tmp");
|
||||
if (!pchReuseFrom) {
|
||||
if (!haveReuseTarget) {
|
||||
cmValue pchPrologue =
|
||||
this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE");
|
||||
cmValue pchEpilogue =
|
||||
@@ -2937,11 +3069,10 @@ std::string cmGeneratorTarget::GetPchSource(std::string const& config,
|
||||
std::string& filename = inserted.first->second;
|
||||
|
||||
cmGeneratorTarget const* generatorTarget = this;
|
||||
cmValue pchReuseFrom =
|
||||
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
if (pchReuseFrom) {
|
||||
generatorTarget =
|
||||
this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
|
||||
cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget();
|
||||
bool const haveReuseTarget = reuseTarget && reuseTarget != this;
|
||||
if (reuseTarget) {
|
||||
generatorTarget = reuseTarget;
|
||||
}
|
||||
|
||||
filename =
|
||||
@@ -2968,7 +3099,7 @@ std::string cmGeneratorTarget::GetPchSource(std::string const& config,
|
||||
}
|
||||
|
||||
std::string const filename_tmp = cmStrCat(filename, ".tmp");
|
||||
if (!pchReuseFrom) {
|
||||
if (!haveReuseTarget) {
|
||||
{
|
||||
cmGeneratedFileStream file(filename_tmp);
|
||||
file << "/* generated by CMake */\n";
|
||||
@@ -3034,11 +3165,9 @@ std::string cmGeneratorTarget::GetPchFile(std::string const& config,
|
||||
};
|
||||
|
||||
cmGeneratorTarget* generatorTarget = this;
|
||||
cmValue pchReuseFrom =
|
||||
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
if (pchReuseFrom) {
|
||||
generatorTarget =
|
||||
this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
|
||||
cmGeneratorTarget* reuseTarget = this->GetPchReuseTarget();
|
||||
if (reuseTarget) {
|
||||
generatorTarget = reuseTarget;
|
||||
}
|
||||
|
||||
std::string const pchFileObject =
|
||||
@@ -4428,7 +4557,12 @@ bool cmGeneratorTarget::ComputePDBOutputDir(std::string const& kind,
|
||||
}
|
||||
}
|
||||
if (out.empty()) {
|
||||
return false;
|
||||
// Compile output should always have a path.
|
||||
if (kind == "COMPILE_PDB"_s) {
|
||||
out = this->GetSupportDirectory();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the output path to a full path in case it is
|
||||
|
||||
@@ -692,6 +692,9 @@ public:
|
||||
std::vector<BT<std::string>> GetPrecompileHeaders(
|
||||
std::string const& config, std::string const& language) const;
|
||||
|
||||
void MarkAsPchReused() { this->PchReused = true; }
|
||||
cmGeneratorTarget const* GetPchReuseTarget() const;
|
||||
cmGeneratorTarget* GetPchReuseTarget();
|
||||
std::vector<std::string> GetPchArchs(std::string const& config,
|
||||
std::string const& lang) const;
|
||||
std::string GetPchHeader(std::string const& config,
|
||||
@@ -1518,6 +1521,9 @@ private:
|
||||
std::map<cmSourceFile const*, ClassifiedFlags> SourceFlags;
|
||||
};
|
||||
mutable std::map<std::string, InfoByConfig> Configs;
|
||||
bool PchReused = false;
|
||||
mutable bool ComputingPchReuse = false;
|
||||
mutable bool PchReuseCycleDetected = false;
|
||||
};
|
||||
|
||||
class cmGeneratorTarget::TargetPropertyEntry
|
||||
|
||||
@@ -387,38 +387,15 @@ bool cmGlobalGenerator::CheckTargetsForType() const
|
||||
return failed;
|
||||
}
|
||||
|
||||
bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
|
||||
void cmGlobalGenerator::MarkTargetsForPchReuse() const
|
||||
{
|
||||
if (!this->GetLanguageEnabled("C") && !this->GetLanguageEnabled("CXX")) {
|
||||
return false;
|
||||
}
|
||||
bool failed = false;
|
||||
for (auto const& generator : this->LocalGenerators) {
|
||||
for (auto const& target : generator->GetGeneratorTargets()) {
|
||||
if (!target->CanCompileSources() ||
|
||||
target->GetProperty("ghs_integrity_app").IsOn()) {
|
||||
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) {
|
||||
std::string const 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;
|
||||
if (auto* reuseTarget = target->GetPchReuseTarget()) {
|
||||
reuseTarget->MarkAsPchReused();
|
||||
}
|
||||
}
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
||||
bool cmGlobalGenerator::IsExportedTargetsFile(
|
||||
@@ -1550,6 +1527,8 @@ bool cmGlobalGenerator::Compute()
|
||||
localGen->AddHelperCommands();
|
||||
}
|
||||
|
||||
this->MarkTargetsForPchReuse();
|
||||
|
||||
// Add automatically generated sources (e.g. unity build).
|
||||
// Add unity sources after computing compile features. Unity sources do
|
||||
// not change the set of languages or features, but we need to know them
|
||||
@@ -1597,10 +1576,6 @@ bool cmGlobalGenerator::Compute()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->CheckTargetsForPchCompilePdb()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto const& localGen : this->LocalGenerators) {
|
||||
localGen->ComputeHomeRelativeOutputPath();
|
||||
}
|
||||
|
||||
@@ -858,7 +858,7 @@ private:
|
||||
void CheckTargetLinkLibraries() const;
|
||||
bool CheckTargetsForMissingSources() const;
|
||||
bool CheckTargetsForType() const;
|
||||
bool CheckTargetsForPchCompilePdb() const;
|
||||
void MarkTargetsForPchReuse() const;
|
||||
|
||||
void CreateLocalGenerators();
|
||||
|
||||
|
||||
@@ -2779,8 +2779,8 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
|
||||
continue;
|
||||
}
|
||||
|
||||
cmValue ReuseFrom =
|
||||
target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
|
||||
auto* reuseTarget = target->GetPchReuseTarget();
|
||||
bool const haveReuseTarget = reuseTarget && reuseTarget != target;
|
||||
|
||||
auto* pch_sf = this->Makefile->GetOrCreateSource(
|
||||
pchSource, false, cmSourceFileLocationKind::Known);
|
||||
@@ -2789,7 +2789,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
|
||||
pch_sf->SetProperty("CXX_SCAN_FOR_MODULES", "0");
|
||||
|
||||
if (!this->GetGlobalGenerator()->IsXcode()) {
|
||||
if (!ReuseFrom) {
|
||||
if (!haveReuseTarget) {
|
||||
target->AddSource(pchSource, true);
|
||||
}
|
||||
|
||||
@@ -2797,14 +2797,11 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
|
||||
|
||||
// Exclude the pch files from linking
|
||||
if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
|
||||
if (!ReuseFrom) {
|
||||
if (!haveReuseTarget) {
|
||||
pch_sf->AppendProperty(
|
||||
"OBJECT_OUTPUTS",
|
||||
cmStrCat("$<$<CONFIG:", config, ">:", pchFile, '>'));
|
||||
} else {
|
||||
auto* reuseTarget =
|
||||
this->GlobalGenerator->FindGeneratorTarget(*ReuseFrom);
|
||||
|
||||
if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
|
||||
|
||||
std::string const compilerId =
|
||||
@@ -2850,11 +2847,11 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
|
||||
}
|
||||
|
||||
if (editAndContinueDebugInfo || msvc2008OrLess) {
|
||||
this->CopyPchCompilePdb(config, lang, target, *ReuseFrom,
|
||||
reuseTarget, { ".pdb", ".idb" });
|
||||
this->CopyPchCompilePdb(config, lang, target, reuseTarget,
|
||||
{ ".pdb", ".idb" });
|
||||
} else if (programDatabaseDebugInfo) {
|
||||
this->CopyPchCompilePdb(config, lang, target, *ReuseFrom,
|
||||
reuseTarget, { ".pdb" });
|
||||
this->CopyPchCompilePdb(config, lang, target, reuseTarget,
|
||||
{ ".pdb" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2906,18 +2903,11 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
|
||||
|
||||
void cmLocalGenerator::CopyPchCompilePdb(
|
||||
std::string const& config, std::string const& language,
|
||||
cmGeneratorTarget* target, std::string const& ReuseFrom,
|
||||
cmGeneratorTarget* reuseTarget, std::vector<std::string> const& extensions)
|
||||
cmGeneratorTarget* target, cmGeneratorTarget* reuseTarget,
|
||||
std::vector<std::string> const& extensions)
|
||||
{
|
||||
std::string const pdb_prefix =
|
||||
this->GetGlobalGenerator()->IsMultiConfig() ? cmStrCat(config, '/') : "";
|
||||
|
||||
std::string const target_compile_pdb_dir =
|
||||
cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
|
||||
target->GetName(), ".dir/");
|
||||
|
||||
std::string const copy_script =
|
||||
cmStrCat(target_compile_pdb_dir, "copy_idb_pdb_", config, ".cmake");
|
||||
std::string const copy_script = cmStrCat(target->GetSupportDirectory(),
|
||||
"/copy_idb_pdb_", config, ".cmake");
|
||||
cmGeneratedFileStream file(copy_script);
|
||||
|
||||
file << "# CMake generated file\n";
|
||||
@@ -2926,28 +2916,37 @@ void cmLocalGenerator::CopyPchCompilePdb(
|
||||
<< "# by mspdbsrv. The foreach retry loop is needed to make sure\n"
|
||||
<< "# the pdb file is ready to be copied.\n\n";
|
||||
|
||||
auto configGenex = [&](cm::string_view expr) -> std::string {
|
||||
if (this->GetGlobalGenerator()->IsMultiConfig()) {
|
||||
return cmStrCat("$<$<CONFIG:", config, ">:", expr, '>');
|
||||
}
|
||||
return std::string(expr);
|
||||
};
|
||||
|
||||
std::vector<std::string> outputs;
|
||||
auto replaceExtension = [](std::string const& path,
|
||||
std::string const& ext) -> std::string {
|
||||
auto const dir = cmSystemTools::GetFilenamePath(path);
|
||||
auto const base = cmSystemTools::GetFilenameWithoutLastExtension(path);
|
||||
if (dir.empty()) {
|
||||
return cmStrCat(base, ext);
|
||||
}
|
||||
return cmStrCat(dir, '/', base, ext);
|
||||
};
|
||||
for (auto const& extension : extensions) {
|
||||
std::string const from_file =
|
||||
cmStrCat(reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
|
||||
'/', ReuseFrom, ".dir/${PDB_PREFIX}", ReuseFrom, extension);
|
||||
|
||||
std::string const to_dir =
|
||||
cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
|
||||
target->GetName(), ".dir/${PDB_PREFIX}");
|
||||
|
||||
std::string const to_file = cmStrCat(to_dir, ReuseFrom, extension);
|
||||
|
||||
std::string dest_file = to_file;
|
||||
|
||||
std::string const& prefix = target->GetSafeProperty("PREFIX");
|
||||
if (!prefix.empty()) {
|
||||
dest_file = cmStrCat(to_dir, prefix, ReuseFrom, extension);
|
||||
}
|
||||
replaceExtension(reuseTarget->GetCompilePDBPath(config), extension);
|
||||
std::string const to_dir = target->GetCompilePDBDirectory(config);
|
||||
std::string const to_file = cmStrCat(
|
||||
replaceExtension(reuseTarget->GetCompilePDBName(config), extension),
|
||||
'/');
|
||||
std::string const dest_file = cmStrCat(to_dir, to_file);
|
||||
|
||||
file << "foreach(retry RANGE 1 30)\n";
|
||||
file << " if (EXISTS \"" << from_file << "\" AND (NOT EXISTS \""
|
||||
<< dest_file << "\" OR NOT \"" << dest_file << " \" IS_NEWER_THAN \""
|
||||
<< dest_file << "\" OR NOT \"" << dest_file << "\" IS_NEWER_THAN \""
|
||||
<< from_file << "\"))\n";
|
||||
file << " file(MAKE_DIRECTORY \"" << to_dir << "\")\n";
|
||||
file << " execute_process(COMMAND ${CMAKE_COMMAND} -E copy";
|
||||
file << " \"" << from_file << "\""
|
||||
<< " \"" << to_dir << "\" RESULT_VARIABLE result "
|
||||
@@ -2956,10 +2955,6 @@ void cmLocalGenerator::CopyPchCompilePdb(
|
||||
<< " execute_process(COMMAND ${CMAKE_COMMAND}"
|
||||
<< " -E sleep 1)\n"
|
||||
<< " else()\n";
|
||||
if (!prefix.empty()) {
|
||||
file << " file(REMOVE \"" << dest_file << "\")\n";
|
||||
file << " file(RENAME \"" << to_file << "\" \"" << dest_file << "\")\n";
|
||||
}
|
||||
file << " break()\n"
|
||||
<< " endif()\n";
|
||||
file << " elseif(NOT EXISTS \"" << from_file << "\")\n"
|
||||
@@ -2967,31 +2962,24 @@ void cmLocalGenerator::CopyPchCompilePdb(
|
||||
<< " -E sleep 1)\n"
|
||||
<< " endif()\n";
|
||||
file << "endforeach()\n";
|
||||
outputs.push_back(configGenex(dest_file));
|
||||
}
|
||||
|
||||
auto configGenex = [&](cm::string_view expr) -> std::string {
|
||||
if (this->GetGlobalGenerator()->IsMultiConfig()) {
|
||||
return cmStrCat("$<$<CONFIG:", config, ">:", expr, '>');
|
||||
}
|
||||
return std::string(expr);
|
||||
};
|
||||
cmCustomCommandLines commandLines =
|
||||
cmMakeSingleCommandLine({ configGenex(cmSystemTools::GetCMakeCommand()),
|
||||
configGenex("-P"), configGenex(copy_script) });
|
||||
|
||||
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
|
||||
{ configGenex(cmSystemTools::GetCMakeCommand()),
|
||||
configGenex(cmStrCat("-DPDB_PREFIX=", pdb_prefix)), configGenex("-P"),
|
||||
configGenex(copy_script) });
|
||||
|
||||
char const* no_message = "";
|
||||
|
||||
std::vector<std::string> outputs;
|
||||
outputs.push_back(configGenex(
|
||||
cmStrCat(target_compile_pdb_dir, pdb_prefix, ReuseFrom, ".pdb")));
|
||||
auto const comment =
|
||||
cmStrCat("Copying PDB for PCH reuse from ", reuseTarget->GetName(),
|
||||
" for ", target->GetName());
|
||||
;
|
||||
|
||||
auto cc = cm::make_unique<cmCustomCommand>();
|
||||
cc->SetCommandLines(commandLines);
|
||||
cc->SetComment(no_message);
|
||||
cc->SetComment(comment.c_str());
|
||||
cc->SetStdPipesUTF8(true);
|
||||
cc->AppendDepends({ reuseTarget->GetPchFile(config, language) });
|
||||
cc->AppendDepends(
|
||||
{ reuseTarget->GetPchFile(config, language), copy_script });
|
||||
|
||||
if (this->GetGlobalGenerator()->IsVisualStudio()) {
|
||||
cc->SetByproducts(outputs);
|
||||
@@ -3007,9 +2995,6 @@ void cmLocalGenerator::CopyPchCompilePdb(
|
||||
target->AddSource(copy_rule->ResolveFullPath());
|
||||
}
|
||||
}
|
||||
|
||||
target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
|
||||
target_compile_pdb_dir);
|
||||
}
|
||||
|
||||
cm::optional<std::string> cmLocalGenerator::GetMSVCDebugFormatName(
|
||||
|
||||
@@ -640,7 +640,6 @@ private:
|
||||
void CopyPchCompilePdb(std::string const& config,
|
||||
std::string const& language,
|
||||
cmGeneratorTarget* target,
|
||||
std::string const& ReuseFrom,
|
||||
cmGeneratorTarget* reuseTarget,
|
||||
std::vector<std::string> const& extensions);
|
||||
|
||||
|
||||
@@ -1911,7 +1911,6 @@ MAKE_PROP(COMPILE_DEFINITIONS);
|
||||
MAKE_PROP(COMPILE_FEATURES);
|
||||
MAKE_PROP(COMPILE_OPTIONS);
|
||||
MAKE_PROP(PRECOMPILE_HEADERS);
|
||||
MAKE_PROP(PRECOMPILE_HEADERS_REUSE_FROM);
|
||||
MAKE_PROP(CUDA_CUBIN_COMPILATION);
|
||||
MAKE_PROP(CUDA_FATBIN_COMPILATION);
|
||||
MAKE_PROP(CUDA_OPTIX_COMPILATION);
|
||||
@@ -2147,38 +2146,6 @@ void cmTarget::SetProperty(std::string const& prop, cmValue value)
|
||||
this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
|
||||
return;
|
||||
}
|
||||
} else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) {
|
||||
if (this->GetProperty("PRECOMPILE_HEADERS")) {
|
||||
std::ostringstream e;
|
||||
e << "PRECOMPILE_HEADERS property is already set on target (\""
|
||||
<< this->impl->Name << "\")\n";
|
||||
this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
|
||||
return;
|
||||
}
|
||||
auto* reusedTarget = this->impl->Makefile->GetCMakeInstance()
|
||||
->GetGlobalGenerator()
|
||||
->FindTarget(value);
|
||||
if (!reusedTarget) {
|
||||
std::string const 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);
|
||||
|
||||
reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom);
|
||||
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
|
||||
cmStrCat(reusedFrom, ".dir/"));
|
||||
|
||||
cmValue tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
|
||||
this->SetProperty("COMPILE_PDB_NAME", tmp);
|
||||
this->AddUtility(reusedFrom, false, this->impl->Makefile);
|
||||
} else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
|
||||
prop == propCUDA_STANDARD || prop == propHIP_STANDARD ||
|
||||
prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD) {
|
||||
@@ -2208,15 +2175,6 @@ void cmTarget::AppendProperty(std::string const& prop,
|
||||
"imported targets (\"",
|
||||
this->impl->Name, "\")\n"));
|
||||
}
|
||||
if (prop == propPRECOMPILE_HEADERS &&
|
||||
this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
|
||||
this->impl->Makefile->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat(
|
||||
"PRECOMPILE_HEADERS_REUSE_FROM property is already set on target (\"",
|
||||
this->impl->Name, "\")\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
UsageRequirementProperty* usageRequirements[] = {
|
||||
&this->impl->IncludeDirectories,
|
||||
|
||||
@@ -76,16 +76,27 @@ endif()
|
||||
|
||||
set(pdbs "")
|
||||
foreach(t ${my_targets})
|
||||
set(with_compile 0)
|
||||
get_property(pdb_name TARGET ${t} PROPERTY PDB_NAME)
|
||||
get_property(pdb_dir TARGET ${t} PROPERTY PDB_OUTPUT_DIRECTORY)
|
||||
if(NOT pdb_name)
|
||||
set(with_compile 1)
|
||||
get_property(pdb_name TARGET ${t} PROPERTY COMPILE_PDB_NAME)
|
||||
endif()
|
||||
if(NOT pdb_dir)
|
||||
get_property(pdb_dir TARGET ${t} PROPERTY COMPILE_PDB_OUTPUT_DIRECTORY)
|
||||
endif()
|
||||
if(NOT pdb_dir)
|
||||
set(pdb_dir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if (NOT with_compile)
|
||||
set(pdb_dir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
elseif (CMAKE_GENERATOR MATCHES "Ninja" OR
|
||||
CMAKE_GENERATOR MATCHES "Makefiles")
|
||||
set(pdb_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${t}.dir)
|
||||
elseif (CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set(pdb_dir ${CMAKE_CURRENT_BINARY_DIR}/${t}.dir)
|
||||
else ()
|
||||
set(pdb_dir ${CMAKE_CURRENT_BINARY_DIR}/${t}.dir)
|
||||
endif ()
|
||||
endif()
|
||||
if (pdb_dir MATCHES "\\$<.*>")
|
||||
# Skip per-configuration subdirectory if the value contained
|
||||
|
||||
@@ -1340,6 +1340,12 @@ add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
|
||||
-DCMAKE_C_SIMULATE_ID=${CMAKE_C_SIMULATE_ID}
|
||||
-DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
|
||||
|
||||
# This test can take a long time due to the number of test cases.
|
||||
# Provide an option to customize it.
|
||||
if(DEFINED CMake_TEST_PrecompileHeaders_TIMEOUT)
|
||||
set_property(TEST RunCMake.PrecompileHeaders PROPERTY TIMEOUT ${CMake_TEST_PrecompileHeaders_TIMEOUT})
|
||||
endif()
|
||||
|
||||
add_RunCMake_test(UnityBuild -DCMake_TEST_OBJC=${CMake_TEST_OBJC} -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
|
||||
set_property(TEST RunCMake.UnityBuild APPEND
|
||||
PROPERTY LABELS "CUDA")
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
((Classic Intel)?Warning #672: the command line options do not match those used[^
|
||||
]*)?
|
||||
60
Tests/RunCMake/PrecompileHeaders/PchReuseAppend.cmake
Normal file
60
Tests/RunCMake/PrecompileHeaders/PchReuseAppend.cmake
Normal file
@@ -0,0 +1,60 @@
|
||||
enable_language(CXX)
|
||||
|
||||
if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
|
||||
add_definitions(-DHAVE_PCH_SUPPORT)
|
||||
endif()
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
|
||||
void nothing()
|
||||
{
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
|
||||
#include <string.h>
|
||||
|
||||
namespace std {
|
||||
struct string
|
||||
{
|
||||
char storage[20];
|
||||
|
||||
string(const char* s) {
|
||||
strcpy(storage, s);
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return storage;
|
||||
}
|
||||
};
|
||||
}
|
||||
]=])
|
||||
|
||||
add_library(pch-generator ${CMAKE_BINARY_DIR}/pch.cxx)
|
||||
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
|
||||
#include "message.hxx"
|
||||
|
||||
#ifndef HAVE_PCH_SUPPORT
|
||||
#include "string.hxx"
|
||||
#endif
|
||||
|
||||
const char* message()
|
||||
{
|
||||
static std::string greeting("hi there");
|
||||
return greeting.c_str();
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
|
||||
const char* message();
|
||||
]=])
|
||||
|
||||
add_library(reuse_append ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_include_directories(reuse_append PRIVATE ${CMAKE_BINARY_DIR})
|
||||
set_property(TARGET reuse_append PROPERTY PRECOMPILE_HEADERS_REUSE_FROM "pch-")
|
||||
set_property(TARGET reuse_append APPEND_STRING PROPERTY PRECOMPILE_HEADERS_REUSE_FROM "generator")
|
||||
@@ -0,0 +1,2 @@
|
||||
((Classic Intel)?Warning #672: the command line options do not match those used[^
|
||||
]*)?
|
||||
79
Tests/RunCMake/PrecompileHeaders/PchReuseConsistency.cmake
Normal file
79
Tests/RunCMake/PrecompileHeaders/PchReuseConsistency.cmake
Normal file
@@ -0,0 +1,79 @@
|
||||
enable_language(CXX)
|
||||
|
||||
if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
|
||||
add_definitions(-DHAVE_PCH_SUPPORT)
|
||||
endif()
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
|
||||
void nothing()
|
||||
{
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
|
||||
#include <string.h>
|
||||
|
||||
namespace std {
|
||||
struct string
|
||||
{
|
||||
char storage[20];
|
||||
|
||||
string(const char* s) {
|
||||
strcpy(storage, s);
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return storage;
|
||||
}
|
||||
};
|
||||
}
|
||||
]=])
|
||||
|
||||
add_library(pch-generator ${CMAKE_BINARY_DIR}/pch.cxx)
|
||||
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
|
||||
#include "message.hxx"
|
||||
|
||||
#ifndef HAVE_PCH_SUPPORT
|
||||
#include "string.hxx"
|
||||
#endif
|
||||
|
||||
const char* message()
|
||||
{
|
||||
static std::string greeting("hi there");
|
||||
return greeting.c_str();
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
|
||||
const char* message();
|
||||
]=])
|
||||
|
||||
add_library(pch_before_reuse_pch ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(pch_before_reuse_pch PRIVATE "${CMAKE_BINARY_DIR}/string.hxx")
|
||||
target_precompile_headers(pch_before_reuse_pch REUSE_FROM pch-generator)
|
||||
set_property(TARGET pch_before_reuse_pch PROPERTY PRECOMPILE_HEADERS_REUSE_FROM)
|
||||
target_include_directories(pch_before_reuse_pch PRIVATE ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_library(pch_before_reuse_reuse ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(pch_before_reuse_reuse PRIVATE "${CMAKE_BINARY_DIR}/string.hxx")
|
||||
target_precompile_headers(pch_before_reuse_reuse REUSE_FROM pch-generator)
|
||||
set_property(TARGET pch_before_reuse_reuse PROPERTY PRECOMPILE_HEADERS "")
|
||||
target_include_directories(pch_before_reuse_reuse PRIVATE ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_library(reuse_before_pch_pch ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(reuse_before_pch_pch REUSE_FROM pch-generator)
|
||||
target_precompile_headers(reuse_before_pch_pch PRIVATE "${CMAKE_BINARY_DIR}/string.hxx")
|
||||
set_property(TARGET reuse_before_pch_pch PROPERTY PRECOMPILE_HEADERS_REUSE_FROM)
|
||||
target_include_directories(reuse_before_pch_pch PRIVATE ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_library(reuse_before_pch_reuse ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(reuse_before_pch_reuse REUSE_FROM pch-generator)
|
||||
target_precompile_headers(reuse_before_pch_reuse PRIVATE "${CMAKE_BINARY_DIR}/string.hxx")
|
||||
set_property(TARGET reuse_before_pch_reuse PROPERTY PRECOMPILE_HEADERS "")
|
||||
target_include_directories(reuse_before_pch_reuse PRIVATE ${CMAKE_BINARY_DIR})
|
||||
@@ -0,0 +1,2 @@
|
||||
((Classic Intel)?Warning #672: the command line options do not match those used[^
|
||||
]*)?
|
||||
@@ -0,0 +1,59 @@
|
||||
enable_language(CXX)
|
||||
|
||||
if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
|
||||
add_definitions(-DHAVE_PCH_SUPPORT)
|
||||
endif()
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
|
||||
#include "message.hxx"
|
||||
|
||||
#ifndef HAVE_PCH_SUPPORT
|
||||
#include "string.hxx"
|
||||
#endif
|
||||
|
||||
const char* message()
|
||||
{
|
||||
static std::string greeting("hi there");
|
||||
return greeting.c_str();
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
|
||||
const char* message();
|
||||
]=])
|
||||
|
||||
add_library(reuse_decl_order ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(reuse_decl_order REUSE_FROM pch-generator)
|
||||
target_include_directories(reuse_decl_order PRIVATE ${CMAKE_BINARY_DIR})
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
|
||||
void nothing()
|
||||
{
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
|
||||
#include <string.h>
|
||||
|
||||
namespace std {
|
||||
struct string
|
||||
{
|
||||
char storage[20];
|
||||
|
||||
string(const char* s) {
|
||||
strcpy(storage, s);
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return storage;
|
||||
}
|
||||
};
|
||||
}
|
||||
]=])
|
||||
|
||||
add_library(pch-generator ${CMAKE_BINARY_DIR}/pch.cxx)
|
||||
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "")
|
||||
string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -Zi")
|
||||
include(PchReuseFrom-common.cmake)
|
||||
include(PchReuseFrom-CMP0141-common.cmake)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
include(PchReuseFrom-common.cmake)
|
||||
include(PchReuseFrom-CMP0141-common.cmake)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
cmake_policy(SET CMP0141 OLD)
|
||||
include(PchReuseFrom-common.cmake)
|
||||
include(PchReuseFrom-CMP0141-common.cmake)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
CMake Error in CMakeLists.txt:
|
||||
Circular PCH reuse target involving 'first'
|
||||
10
Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle.cmake
Normal file
10
Tests/RunCMake/PrecompileHeaders/PchReuseFromCycle.cmake
Normal file
@@ -0,0 +1,10 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(first foo.c)
|
||||
target_precompile_headers(first REUSE_FROM third)
|
||||
|
||||
add_library(second foo.c)
|
||||
target_precompile_headers(second REUSE_FROM first)
|
||||
|
||||
add_library(third foo.c)
|
||||
target_precompile_headers(third REUSE_FROM second)
|
||||
@@ -0,0 +1,19 @@
|
||||
if(MSVC OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_SIMULATE_ID STREQUAL "MSVC"))
|
||||
find_file(pdb_file
|
||||
NAMES NOT_USED.pdb
|
||||
PATHS "${RunCMake_TEST_BINARY_DIR}"
|
||||
PATH_SUFFIXES NOT_USED NOT_USED_DEBUG)
|
||||
if (EXISTS "${pdb_file}")
|
||||
list(APPEND RunCMake_TEST_FAILED
|
||||
"PDB file was created from properties meant to be ignored")
|
||||
endif ()
|
||||
|
||||
if (EXISTS "${RunCMake_TEST_BINARY_DIR}/mycustomdir")
|
||||
list(APPEND RunCMake_TEST_FAILED
|
||||
"PDB output directory ('mycustomdir') was created (should have used debug variant)")
|
||||
endif ()
|
||||
if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/mycustomdir_debug")
|
||||
list(APPEND RunCMake_TEST_FAILED
|
||||
"PDB output directory ('mycustomdir_debug') was not created (separate PDBs required)")
|
||||
endif ()
|
||||
endif ()
|
||||
@@ -0,0 +1,2 @@
|
||||
((Classic Intel)?Warning #672: the command line options do not match those used[^
|
||||
]*)?
|
||||
@@ -0,0 +1,66 @@
|
||||
enable_language(CXX)
|
||||
|
||||
if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
|
||||
add_definitions(-DHAVE_PCH_SUPPORT)
|
||||
endif()
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
|
||||
void nothing()
|
||||
{
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
|
||||
#include <string.h>
|
||||
|
||||
namespace std {
|
||||
struct string
|
||||
{
|
||||
char storage[20];
|
||||
|
||||
string(const char* s) {
|
||||
strcpy(storage, s);
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return storage;
|
||||
}
|
||||
};
|
||||
}
|
||||
]=])
|
||||
|
||||
add_library(pch-generator ${CMAKE_BINARY_DIR}/pch.cxx)
|
||||
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
|
||||
#include "message.hxx"
|
||||
|
||||
#ifndef HAVE_PCH_SUPPORT
|
||||
#include "string.hxx"
|
||||
#endif
|
||||
|
||||
const char* message()
|
||||
{
|
||||
static std::string greeting("hi there");
|
||||
return greeting.c_str();
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
|
||||
const char* message();
|
||||
]=])
|
||||
|
||||
add_library(ignored_props ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(ignored_props REUSE_FROM pch-generator)
|
||||
target_include_directories(ignored_props PRIVATE ${CMAKE_BINARY_DIR})
|
||||
|
||||
set_target_properties(ignored_props
|
||||
PROPERTIES
|
||||
COMPILE_PDB_NAME "NOT_USED"
|
||||
COMPILE_PDB_NAME_DEBUG "NOT_USED_DEBUG"
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/mycustomdir"
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/mycustomdir_debug")
|
||||
@@ -0,0 +1,16 @@
|
||||
if(MSVC)
|
||||
find_file(pdb_file
|
||||
NAMES custom-post.pdb custom-post-debug.pdb
|
||||
PATHS "${RunCMake_TEST_BINARY_DIR}"
|
||||
PATH_SUFFIXES custom custom-debug)
|
||||
if (NOT EXISTS "${pdb_file}")
|
||||
list(APPEND RunCMake_TEST_FAILED
|
||||
"PDB file was not created from properties updated after reuse link")
|
||||
endif ()
|
||||
|
||||
if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/custom" AND
|
||||
NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/custom-debug")
|
||||
list(APPEND RunCMake_TEST_FAILED
|
||||
"Updated PDB output directory ('custom' or 'custom-debug') was not created")
|
||||
endif ()
|
||||
endif ()
|
||||
@@ -0,0 +1,2 @@
|
||||
((Classic Intel)?Warning #672: the command line options do not match those used[^
|
||||
]*)?
|
||||
@@ -0,0 +1,66 @@
|
||||
enable_language(CXX)
|
||||
|
||||
if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
|
||||
add_definitions(-DHAVE_PCH_SUPPORT)
|
||||
endif()
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
|
||||
void nothing()
|
||||
{
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
|
||||
#include <string.h>
|
||||
|
||||
namespace std {
|
||||
struct string
|
||||
{
|
||||
char storage[20];
|
||||
|
||||
string(const char* s) {
|
||||
strcpy(storage, s);
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return storage;
|
||||
}
|
||||
};
|
||||
}
|
||||
]=])
|
||||
|
||||
add_library(pch-generator ${CMAKE_BINARY_DIR}/pch.cxx)
|
||||
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
|
||||
#include "message.hxx"
|
||||
|
||||
#ifndef HAVE_PCH_SUPPORT
|
||||
#include "string.hxx"
|
||||
#endif
|
||||
|
||||
const char* message()
|
||||
{
|
||||
static std::string greeting("hi there");
|
||||
return greeting.c_str();
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
|
||||
const char* message();
|
||||
]=])
|
||||
|
||||
add_library(updated_props ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(updated_props REUSE_FROM pch-generator)
|
||||
target_include_directories(updated_props PRIVATE ${CMAKE_BINARY_DIR})
|
||||
|
||||
set_target_properties(pch-generator
|
||||
PROPERTIES
|
||||
COMPILE_PDB_NAME "custom-post"
|
||||
COMPILE_PDB_NAME_DEBUG "custom-post-debug"
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/custom"
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/custom-debug")
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,4 @@
|
||||
CMake Error in CMakeLists.txt:
|
||||
Target "pch-generator" for the "reuse_from_nopch" target's
|
||||
"PRECOMPILE_HEADERS_REUSE_FROM" property has set
|
||||
"DISABLE_PRECOMPILE_HEADERS".
|
||||
60
Tests/RunCMake/PrecompileHeaders/PchReuseWithoutPch.cmake
Normal file
60
Tests/RunCMake/PrecompileHeaders/PchReuseWithoutPch.cmake
Normal file
@@ -0,0 +1,60 @@
|
||||
enable_language(CXX)
|
||||
|
||||
if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
|
||||
add_definitions(-DHAVE_PCH_SUPPORT)
|
||||
endif()
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
|
||||
void nothing()
|
||||
{
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
|
||||
#include <string.h>
|
||||
|
||||
namespace std {
|
||||
struct string
|
||||
{
|
||||
char storage[20];
|
||||
|
||||
string(const char* s) {
|
||||
strcpy(storage, s);
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
return storage;
|
||||
}
|
||||
};
|
||||
}
|
||||
]=])
|
||||
|
||||
add_library(pch-generator ${CMAKE_BINARY_DIR}/pch.cxx)
|
||||
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)
|
||||
set_property(TARGET pch-generator PROPERTY DISABLE_PRECOMPILE_HEADERS 1)
|
||||
|
||||
######################################################################
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
|
||||
#include "message.hxx"
|
||||
|
||||
#ifndef HAVE_PCH_SUPPORT
|
||||
#include "string.hxx"
|
||||
#endif
|
||||
|
||||
const char* message()
|
||||
{
|
||||
static std::string greeting("hi there");
|
||||
return greeting.c_str();
|
||||
}
|
||||
]=])
|
||||
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
|
||||
const char* message();
|
||||
]=])
|
||||
|
||||
add_library(reuse_from_nopch ${CMAKE_BINARY_DIR}/message.cxx)
|
||||
target_precompile_headers(reuse_from_nopch REUSE_FROM pch-generator)
|
||||
target_include_directories(reuse_from_nopch PRIVATE ${CMAKE_BINARY_DIR})
|
||||
@@ -8,6 +8,13 @@ function(run_test name)
|
||||
run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
|
||||
endfunction()
|
||||
|
||||
function(run_build_verbose name)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
|
||||
run_cmake(${name})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --verbose --config Debug)
|
||||
endfunction()
|
||||
|
||||
run_cmake(DisabledPch)
|
||||
run_cmake(PchDebugGenex)
|
||||
run_test(PchInterface)
|
||||
@@ -22,7 +29,14 @@ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
endif()
|
||||
run_test(PchReuseFromPrefixed)
|
||||
run_test(PchReuseFromSubdir)
|
||||
run_build_verbose(PchReuseFromIgnoreOwnProps)
|
||||
run_build_verbose(PchReuseFromUseUpdatedProps)
|
||||
run_build_verbose(PchReuseConsistency)
|
||||
run_cmake(PchReuseFromCycle)
|
||||
run_cmake(PchReuseWithoutPch)
|
||||
run_build_verbose(PchReuseAppend)
|
||||
run_cmake(PchMultilanguage)
|
||||
run_build_verbose(PchReuseDeclarationOrder)
|
||||
if(RunCMake_GENERATOR MATCHES "Make|Ninja")
|
||||
run_cmake(PchWarnInvalid)
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ run_cmake(VsDpiAware)
|
||||
run_cmake(VsDpiAwareBadParam)
|
||||
run_cmake(VsForceInclude)
|
||||
run_cmake(VsPrecompileHeaders)
|
||||
run_cmake(VsPrecompileHeadersReuseFromCompilePDBName)
|
||||
run_cmake(VsDeployEnabled)
|
||||
run_cmake(VsSettings)
|
||||
run_cmake(VsSourceSettingsTool)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
CMake Error at VsPrecompileHeadersReuseFromCompilePDBName.cmake:6 \(add_library\):
|
||||
PRECOMPILE_HEADERS_REUSE_FROM property is set on target \("b"\). Reusable
|
||||
precompile headers requires the COMPILE_PDB_NAME property to have the value
|
||||
"a"
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
@@ -1,9 +0,0 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user