FILE_SET: add SKIP_PRECOMPILE_HEADERS property support

This commit is contained in:
Marc Chevrier
2026-06-01 18:39:23 +02:00
parent 53198548ea
commit c06d409f12
17 changed files with 103 additions and 31 deletions
+1
View File
@@ -554,6 +554,7 @@ Properties on File Sets
/prop_fs/INTERFACE_SOURCES
/prop_fs/SCOPE
/prop_fs/SKIP_LINTING
/prop_fs/SKIP_PRECOMPILE_HEADERS
/prop_fs/SKIP_UNITY_BUILD_INCLUSION
/prop_fs/SOURCES
/prop_fs/TYPE
+20
View File
@@ -0,0 +1,20 @@
SKIP_PRECOMPILE_HEADERS
-----------------------
.. versionadded:: 4.4
The file set sources will be skipped by :prop_tgt:`PRECOMPILE_HEADERS` feature.
This property helps with build problems that one would run into
when using the :prop_tgt:`PRECOMPILE_HEADERS` feature.
One example would be the usage of Objective-C (``*.m``) files, and
Objective-C++ (``*.mm``) files, which lead to compilation failure
because they are treated (in case of Ninja / Makefile generator)
as C, and CXX respectively. The precompile headers are not
compatible between languages.
See Also
^^^^^^^^
* :prop_sf:`SKIP_PRECOMPILE_HEADERS` source file property
+5
View File
@@ -13,3 +13,8 @@ Objective-C++ (``*.mm``) files, which lead to compilation failure
because they are treated (in case of Ninja / Makefile generator)
as C, and CXX respectively. The precompile headers are not
compatible between languages.
See Also
^^^^^^^^
* :prop_fs:`SKIP_PRECOMPILE_HEADERS` file set property
@@ -0,0 +1,5 @@
FILE_SET-SKIP_PRECOMPILE_HEADERS
--------------------------------
* File sets gained the support of the :prop_fs:`SKIP_PRECOMPILE_HEADERS` file
set property.
+11 -3
View File
@@ -490,6 +490,13 @@ void cmFastbuildNormalTargetGenerator::ComputePCH(
if (srcFile.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
return;
}
cmGeneratorFileSet const* const fileSet =
this->GeneratorTarget->GetFileSetForSource(Config, &srcFile);
if (fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
return;
}
// We have already computed PCH for this node.
if (!node.PCHOptions.empty() || !node.PCHInputFile.empty() ||
!node.PCHOutputFile.empty()) {
@@ -1456,10 +1463,10 @@ void cmFastbuildNormalTargetGenerator::GenerateObjects(FastbuildTarget& target)
cmSourceFile const& srcFile = *source;
std::string const pathToFile = srcFile.GetFullPath();
cmGeneratorFileSet const* const fileSet =
GeneratorTarget->GetFileSetForSource(Config, source);
bool fileUsesUnity = useUnity;
if (useUnity) {
cmGeneratorFileSet const* fileSet =
GeneratorTarget->GetFileSetForSource(Config, source);
// Check if the source should be added to "UnityInputExcludedFiles".
if (IsExcludedFromUnity(GeneratorTarget, fileSet, srcFile)) {
fileUsesUnity = false;
@@ -1518,7 +1525,8 @@ void cmFastbuildNormalTargetGenerator::GenerateObjects(FastbuildTarget& target)
std::string const objectListHash = hash.HashString(cmStrCat(
compileOptions, staticCheckOptions, objOutDirWithPossibleSubdir,
// If file does not need PCH - it must be in another ObjectList.
srcFile.GetProperty("SKIP_PRECOMPILE_HEADERS"),
(fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
srcFile.GetProperty("SKIP_PRECOMPILE_HEADERS"),
srcFile.GetLanguage()));
LogMessage("ObjectList Hash: " + objectListHash);
+3 -1
View File
@@ -1545,7 +1545,9 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
}
}
if (!pchSources.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!pchSources.empty() &&
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
sf->GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
std::string pchOptions;
auto pchIt = pchSources.find(sf->ResolveFullPath());
if (pchIt != pchSources.end()) {
+2 -1
View File
@@ -2395,7 +2395,8 @@ cmGeneratorTarget::GetClassifiedFlagsForSource(cmSourceFile const* sf,
std::string pchFlags;
// Add precompile headers compile options.
if (!sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!((fileSet && sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
sf->GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
if (!pchSources.empty()) {
std::string pchOptions;
auto pchIt = pchSources.find(sf->GetFullPath());
+2 -1
View File
@@ -1141,7 +1141,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
}
}
if (sf->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
if ((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
sf->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
this->AppendDefines(flagsBuild, "CMAKE_SKIP_PRECOMPILE_HEADERS", true);
}
+5 -2
View File
@@ -2746,9 +2746,12 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
for (std::string const& lang : langs) {
auto langSources = std::count_if(
sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
sources.begin(), sources.end(),
[&target, &config, &lang](cmSourceFile* sf) {
auto const* const fileSet = target->GetFileSetForSource(config, sf);
return lang == sf->GetLanguage() &&
!sf->GetProperty("SKIP_PRECOMPILE_HEADERS");
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
sf->GetProperty("SKIP_PRECOMPILE_HEADERS"));
});
if (langSources == 0) {
continue;
+3 -1
View File
@@ -1531,7 +1531,9 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
// Add precompile headers compile options.
std::string const pchSource = gt->GetPchSource(config, lang);
if (!pchSource.empty() && !sf.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!pchSource.empty() &&
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
sf.GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
std::string pchOptions;
if (sf.GetFullPath() == pchSource) {
pchOptions = gt->GetPchCreateCompileOptions(config, lang);
+10 -8
View File
@@ -29,7 +29,6 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorFileSet.h"
#include "cmGeneratorFileSets.h"
#include "cmGeneratorOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -665,6 +664,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string const config = this->GetConfigName();
std::string const configUpper = cmSystemTools::UpperCase(config);
// lookup for the associated file set, if any.
auto const* fileSet =
this->GeneratorTarget->GetFileSetForSource(config, &source);
// Add precompile headers dependencies
std::vector<std::string> pchArchs =
this->GeneratorTarget->GetPchArchs(config, lang);
@@ -682,7 +685,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
}
if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!pchSources.empty() &&
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
source.GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
for (std::string const& arch : pchArchs) {
std::string const& pchHeader =
this->GeneratorTarget->GetPchHeader(config, lang, arch);
@@ -751,11 +756,6 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
ispcHeaderRelative, cmOutputConverter::SHELL);
}
// lookup for the associated file set, if any.
auto const* fileSet =
this->GeneratorTarget->GetGeneratorFileSets()->GetFileSetForSource(
config, &source);
// Add flags from source file properties.
std::string const COMPILE_FLAGS("COMPILE_FLAGS");
if (cmValue cflags = source.GetProperty(COMPILE_FLAGS)) {
@@ -794,7 +794,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Add precompile headers compile options.
if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!pchSources.empty() &&
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
source.GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
std::string pchOptions;
auto const pchIt = pchSources.find(source.GetFullPath());
if (pchIt != pchSources.end()) {
+16 -9
View File
@@ -249,9 +249,11 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
if (auto const* fileSet =
this->GeneratorTarget->GetGeneratorFileSets()->GetFileSetForSource(
config, source)) {
auto const* const fileSet =
this->GeneratorTarget->GetGeneratorFileSets()->GetFileSetForSource(config,
source);
if (fileSet) {
auto options = fileSet->BelongsTo(this->GeneratorTarget)
? fileSet->GetCompileOptions(config, language)
: fileSet->GetInterfaceCompileOptions(config, language);
@@ -262,7 +264,9 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
// Add precompile headers compile options.
if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!pchSources.empty() &&
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
source->GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
std::string pchOptions;
auto pchIt = pchSources.find(source->GetFullPath());
if (pchIt != pchSources.end()) {
@@ -277,14 +281,13 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
}
auto const* fs = this->GeneratorTarget->GetFileSetForSource(config, source);
if (fs && fs->GetType() == cm::FileSetMetadata::CXX_MODULES) {
if (fileSet && fileSet->GetType() == cm::FileSetMetadata::CXX_MODULES) {
if (source->GetLanguage() != "CXX"_s) {
this->GetMakefile()->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Target \"", this->GeneratorTarget->Target->GetName(),
"\" contains the source\n ", source->GetFullPath(),
"\nin a file set of type \"", fs->GetType(),
"\nin a file set of type \"", fileSet->GetType(),
R"(" but the source is not classified as a "CXX" source.)"));
}
@@ -1678,7 +1681,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
}
if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!pchSources.empty() &&
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
source->GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
for (std::string const& arch : pchArchs) {
depList.push_back(
this->GeneratorTarget->GetPchHeader(config, language, arch));
@@ -1832,7 +1837,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->addPoolNinjaVariable("JOB_POOL_COMPILE", config,
this->GetGeneratorTarget(), source, vars);
if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
if (!pchSources.empty() &&
!((fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
source->GetProperty("SKIP_PRECOMPILE_HEADERS"))) {
auto pchIt = pchSources.find(source->GetFullPath());
if (pchIt != pchSources.end()) {
this->addPoolNinjaVariable("JOB_POOL_PRECOMPILE_HEADER", config,
+5 -3
View File
@@ -2743,7 +2743,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
"\nin a \"FILE_SET TYPE ", cm::FileSetMetadata::CXX_MODULES,
"\" but it is not scheduled for compilation."));
}
if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
if ((fs && fs->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
e2.Element("PrecompiledHeader", "NotUsing");
}
if (!isCSharp && !exclude_configs.empty()) {
@@ -2965,8 +2966,9 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
this->GeneratorTarget->GetLinkerLanguage(config);
std::string const& pchSource =
this->GeneratorTarget->GetPchSource(config, lang);
bool const skipPCH =
pchSource.empty() || sf.GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS");
bool const skipPCH = pchSource.empty() ||
(fileSet && fileSet->GetProperty("SKIP_PRECOMPILE_HEADERS")) ||
sf.GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS");
bool const makePCH = (sf.GetFullPath() == pchSource);
bool const useSharedPCH = !skipPCH && (lang == linkLanguage);
bool const useDifferentLangPCH = !skipPCH && (lang != linkLanguage);
@@ -5,10 +5,17 @@ enable_language(CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(pch-test main.cpp non-pch.cpp)
add_executable(pch-test main.cpp non-pch1.cpp)
target_precompile_headers(pch-test PRIVATE pch.h)
set_source_files_properties(non-pch.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
set_source_files_properties(non-pch1.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
target_sources(pch-test PRIVATE FILE_SET f1 TYPE SOURCES FILES non-pch2.cpp)
set_property(FILE_SET f1 TARGET pch-test PROPERTY SKIP_PRECOMPILE_HEADERS ON)
target_sources(pch-test PRIVATE FILE_SET f2 TYPE SOURCES FILES non-pch3.cpp)
set_source_files_properties(non-pch3.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
enable_testing()
add_test(NAME pch-test COMMAND pch-test)
@@ -0,0 +1,3 @@
#ifdef PCH_INCLUDED
# error "PCH must not be included into this file!"
#endif
@@ -0,0 +1,3 @@
#ifdef PCH_INCLUDED
# error "PCH must not be included into this file!"
#endif