1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-18 17:31:57 +08:00

pchreuse: always ask the PCH reuse target for PDB information

The property settings set things up once, but nothing ensures that
post-reuse hookup that any property changes propagate. Instead, when
computing PDB information, if PCH reuse is enabled, just always use its
values.

Also drop enforcement at generate time of property value consistency as
it is now ignored when PCH reuse is in effect.

Additionally, if a target is PCH-reused, generate a PDB output directory
for it.

The `PchReuseFromIgnoreOwnProps` test failed previously because the
post-reuse link update of the consuming `PDB` properties are no longer
considered. The `PchReuseFromUseUpdatedProps` failed because the
post-reuse link did not update the copy of the properties added to
consuming reuse target properties.
This commit is contained in:
Ben Boeckel
2025-06-15 00:07:45 +02:00
parent 6e7da8aa95
commit 1d701491a2
20 changed files with 220 additions and 56 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1269,6 +1269,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 +1296,12 @@ std::string cmGeneratorTarget::GetCompilePDBName(
return components.prefix + pdbName + ".pdb";
}
if (this->PchReused) {
NameComponents const& components = GetFullNameInternalComponents(
config, cmStateEnums::RuntimeBinaryArtifact);
return cmStrCat(components.prefix, this->GetName(), ".pdb");
}
return "";
}
@@ -4441,7 +4453,14 @@ bool cmGeneratorTarget::ComputePDBOutputDir(std::string const& kind,
}
}
if (out.empty()) {
return false;
// A target which is PCH-reused must have a stable PDB output directory so
// that the PDB can be stably referred to when consuming the PCH file.
if (this->PchReused) {
out = cmStrCat(this->GetLocalGenerator()->GetCurrentBinaryDirectory(),
'/', this->GetName(), ".dir/");
} else {
return false;
}
}
// Convert the output path to a full path in case it is

View File

@@ -692,6 +692,7 @@ 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,
@@ -1520,6 +1521,7 @@ private:
std::map<cmSourceFile const*, ClassifiedFlags> SourceFlags;
};
mutable std::map<std::string, InfoByConfig> Configs;
bool PchReused = false;
};
class cmGeneratorTarget::TargetPropertyEntry

View File

@@ -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();
}

View File

@@ -858,7 +858,7 @@ private:
void CheckTargetLinkLibraries() const;
bool CheckTargetsForMissingSources() const;
bool CheckTargetsForType() const;
bool CheckTargetsForPchCompilePdb() const;
void MarkTargetsForPchReuse() const;
void CreateLocalGenerators();

View File

@@ -2172,12 +2172,6 @@ void cmTarget::SetProperty(std::string const& prop, cmValue 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 ||

View File

@@ -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 ()

View File

@@ -0,0 +1,2 @@
((Classic Intel)?Warning #672: the command line options do not match those used[^
]*)?

View File

@@ -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")

View File

@@ -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 ()

View File

@@ -0,0 +1,2 @@
((Classic Intel)?Warning #672: the command line options do not match those used[^
]*)?

View File

@@ -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")

View File

@@ -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,6 +29,8 @@ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
endif()
run_test(PchReuseFromPrefixed)
run_test(PchReuseFromSubdir)
run_build_verbose(PchReuseFromIgnoreOwnProps)
run_build_verbose(PchReuseFromUseUpdatedProps)
run_cmake(PchMultilanguage)
if(RunCMake_GENERATOR MATCHES "Make|Ninja")
run_cmake(PchWarnInvalid)

View File

@@ -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)

View File

@@ -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\)

View File

@@ -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)