Browse Source

Unity: Don't include sources with HEADER_FILE_ONLY property set

Fixes: #19946
Fixes: #19947
Co-authored-by: Craig Scott <[email protected]>
Cristian Adam 6 years ago
parent
commit
9a5418320e

+ 1 - 0
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;
   }
 

+ 19 - 0
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<std::string>& result,
                                        const std::string& config,
                                        const std::string& language) const

+ 8 - 1
Source/cmGeneratorTarget.h

@@ -10,6 +10,7 @@
 #include <set>
 #include <string>
 #include <unordered_map>
+#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -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<std::string, std::string> PchCreateCompileOptions;
   mutable std::map<std::string, std::string> PchUseCompileOptions;
 
+  std::unordered_set<std::string> UnityBatchedSourceFiles;
+
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config,
                        const cmGeneratorTarget* headTarget,

+ 3 - 1
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.

+ 3 - 3
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());
 

+ 1 - 0
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:

+ 1 - 0
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()

+ 3 - 3
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()
 

+ 4 - 1
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)