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:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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 ||
|
||||
|
@@ -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")
|
@@ -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)
|
||||
|
@@ -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 +0,0 @@
|
||||
1
|
@@ -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