From 9a5418320ea40d61a63fd47e5ac133c3ff780062 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Sat, 9 Nov 2019 14:28:18 +1100 Subject: Unity: Don't include sources with HEADER_FILE_ONLY property set Fixes: #19946 Fixes: #19947 Co-authored-by: Craig Scott --- Source/cmFileAPICodemodel.cxx | 1 + Source/cmGeneratorTarget.cxx | 19 +++++++++++++++++++ Source/cmGeneratorTarget.h | 9 ++++++++- Source/cmGlobalXCodeGenerator.cxx | 4 +++- Source/cmLocalGenerator.cxx | 6 +++--- Source/cmVisualStudio10TargetGenerator.cxx | 1 + Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake | 1 + Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake | 6 +++--- Tests/RunCMake/UnityBuild/unitybuild_skip.cmake | 5 ++++- 9 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 48561de..5cc4a26 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -1081,6 +1081,7 @@ Json::Value Target::DumpSource(cmGeneratorTarget::SourceAndKind const& sk, case cmGeneratorTarget::SourceKindModuleDefinition: case cmGeneratorTarget::SourceKindResx: case cmGeneratorTarget::SourceKindXaml: + case cmGeneratorTarget::SourceKindUnityBatched: break; } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index f235af9..77b2a17 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1569,6 +1569,8 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, kind = SourceKindCustomCommand; } else if (this->Target->GetType() == cmStateEnums::UTILITY) { kind = SourceKindExtra; + } else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) { + kind = SourceKindUnityBatched; } else if (sf->GetPropertyAsBool("HEADER_FILE_ONLY")) { kind = SourceKindHeader; } else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) { @@ -3594,6 +3596,23 @@ std::string cmGeneratorTarget::GetPchUseCompileOptions( return inserted.first->second; } +void cmGeneratorTarget::AddSourceFileToUnityBatch( + const std::string& sourceFilename) +{ + this->UnityBatchedSourceFiles.insert(sourceFilename); +} + +bool cmGeneratorTarget::IsSourceFilePartOfUnityBatch( + const std::string& sourceFilename) const +{ + if (!this->GetPropertyAsBool("UNITY_BUILD")) { + return false; + } + + return this->UnityBatchedSourceFiles.find(sourceFilename) != + this->UnityBatchedSourceFiles.end(); +} + void cmGeneratorTarget::GetLinkOptions(std::vector& result, const std::string& config, const std::string& language) const diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 1f824b1..493eafc 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -98,7 +99,8 @@ public: SourceKindModuleDefinition, SourceKindObjectSource, SourceKindResx, - SourceKindXaml + SourceKindXaml, + SourceKindUnityBatched }; /** A source file paired with a kind (classification). */ @@ -471,6 +473,9 @@ public: std::string GetPchUseCompileOptions(const std::string& config, const std::string& language); + void AddSourceFileToUnityBatch(const std::string& sourceFilename); + bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const; + bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config, const std::string& language) const; @@ -893,6 +898,8 @@ private: mutable std::map PchCreateCompileOptions; mutable std::map PchUseCompileOptions; + std::unordered_set UnityBatchedSourceFiles; + void ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, const cmGeneratorTarget* headTarget, diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index adeb065..d154c6e 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1174,7 +1174,9 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget( headerFiles.push_back(xsf); } else if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource) { resourceFiles.push_back(xsf); - } else if (!sourceFile->GetPropertyAsBool("HEADER_FILE_ONLY")) { + } else if (!sourceFile->GetPropertyAsBool("HEADER_FILE_ONLY") && + !gtgt->IsSourceFilePartOfUnityBatch( + sourceFile->ResolveFullPath())) { // Include this file in the build if it has a known language // and has not been listed as an ignored extension for this // generator. diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index cae47e0..5d2c927 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2441,6 +2441,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) std::back_inserter(filtered_sources), [&](cmSourceFile* sf) { return sf->GetLanguage() == lang && !sf->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION") && + !sf->GetPropertyAsBool("HEADER_FILE_ONLY") && !sf->GetProperty("COMPILE_OPTIONS") && !sf->GetProperty("COMPILE_DEFINITIONS") && !sf->GetProperty("COMPILE_FLAGS") && @@ -2475,11 +2476,10 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) cmSourceFile* sf = filtered_sources[begin]; // Only in Visual Studio generator we keep the source files - // for explicit processing. For the rest the source files will - // not be included in the project. + // for explicit processing. if (!this->GetGlobalGenerator()->IsMultiConfig() || this->GetGlobalGenerator()->IsXcode()) { - sf->SetProperty("HEADER_FILE_ONLY", "ON"); + target->AddSourceFileToUnityBatch(sf->ResolveFullPath()); } sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str()); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 3843bf2..94b6495 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2141,6 +2141,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0) this->WriteExtraSource(e1, si.Source); break; case cmGeneratorTarget::SourceKindHeader: + case cmGeneratorTarget::SourceKindUnityBatched: this->WriteHeaderSource(e1, si.Source); break; case cmGeneratorTarget::SourceKindIDL: diff --git a/Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake b/Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake index 8816299..3589cc8 100644 --- a/Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake +++ b/Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake @@ -2,6 +2,7 @@ project(unitybuild_runtest C) set(CMAKE_UNITY_BUILD ON) # This tests that the variable works in addition to the property +add_library(lib main.c func.c) add_executable(main main.c func.c) enable_testing() diff --git a/Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake index 61419d8..fdd45bc 100644 --- a/Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake +++ b/Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake @@ -1,9 +1,9 @@ set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c") file(STRINGS ${unitybuild_c} unitybuild_c_strings) -string(REGEX MATCH "\\/s[2-6].c" matched_files_2_6 ${unitybuild_c_strings}) -if(matched_files_2_6) - set(RunCMake_TEST_FAILED "Generated unity contains s2.c -> s6.c which should have been skipped") +string(REGEX MATCH "\\/s[1-6].c" matched_files_1_6 ${unitybuild_c_strings}) +if(matched_files_1_6) + set(RunCMake_TEST_FAILED "Generated unity contains s1.c -> s6.c which should have been skipped") return() endif() diff --git a/Tests/RunCMake/UnityBuild/unitybuild_skip.cmake b/Tests/RunCMake/UnityBuild/unitybuild_skip.cmake index eef8ccc..94e5aa3 100644 --- a/Tests/RunCMake/UnityBuild/unitybuild_skip.cmake +++ b/Tests/RunCMake/UnityBuild/unitybuild_skip.cmake @@ -1,7 +1,7 @@ project(unitybuild_skip C) set(srcs "") -foreach(s RANGE 2 8) +foreach(s RANGE 1 8) set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") file(WRITE "${src}" "int s${s}(void) { return 0; }\n") list(APPEND srcs "${src}") @@ -11,6 +11,9 @@ add_library(tgt SHARED ${srcs}) set_target_properties(tgt PROPERTIES UNITY_BUILD ON) +set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s1.c + PROPERTIES HEADER_FILE_ONLY ON) + set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s2.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) -- cgit v0.12