summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmLocalGenerator.cxx85
-rw-r--r--Source/cmLocalGenerator.h1
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx1
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx1
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx1
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx1
-rw-r--r--Source/cmTarget.cxx2
7 files changed, 92 insertions, 0 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 7177694..6fade3e 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -38,6 +38,7 @@
#include <algorithm>
#include <assert.h>
+#include <cstdlib>
#include <functional>
#include <initializer_list>
#include <iterator>
@@ -2202,6 +2203,90 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target,
}
}
+void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target,
+ const std::string& config)
+{
+ if (!target->GetPropertyAsBool("UNITY_BUILD")) {
+ return;
+ }
+
+ const std::string buildType = cmSystemTools::UpperCase(config);
+
+ std::string filename_base =
+ cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/",
+ target->GetName(), ".dir/Unity/");
+
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, buildType);
+
+ auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
+ const size_t unityBatchSize =
+ static_cast<size_t>(std::atoi(batchSizeString));
+
+ auto beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
+ auto afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+
+ for (std::string lang : { "C", "CXX" }) {
+ std::vector<cmSourceFile*> filtered_sources;
+ std::copy_if(sources.begin(), sources.end(),
+ std::back_inserter(filtered_sources), [&](cmSourceFile* sf) {
+ return sf->GetLanguage() == lang &&
+ !sf->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION") &&
+ !sf->GetPropertyAsBool("GENERATED") &&
+ !sf->GetProperty("COMPILE_OPTIONS") &&
+ !sf->GetProperty("COMPILE_DEFINITIONS") &&
+ !sf->GetProperty("COMPILE_FLAGS") &&
+ !sf->GetProperty("INCLUDE_DIRECTORIES");
+ });
+
+ size_t batchSize = unityBatchSize;
+ if (unityBatchSize == 0) {
+ batchSize = filtered_sources.size();
+ }
+
+ for (size_t itemsLeft = filtered_sources.size(), chunk = batchSize,
+ batch = 0;
+ itemsLeft > 0; itemsLeft -= chunk, ++batch) {
+
+ chunk = std::min(itemsLeft, batchSize);
+
+ std::string filename = cmStrCat(filename_base, "unity_", batch,
+ (lang == "C") ? ".c" : ".cxx");
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ size_t begin = batch * batchSize;
+ size_t end = begin + chunk;
+
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ this->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+
+ for (; begin != end; ++begin) {
+ cmSourceFile* sf = filtered_sources[begin];
+
+ sf->SetProperty("HEADER_FILE_ONLY", "ON");
+
+ if (beforeInclude) {
+ file << beforeInclude << "\n";
+ }
+
+ file << "#include \"" << sf->GetFullPath() << "\"\n";
+
+ if (afterInclude) {
+ file << afterInclude << "\n";
+ }
+ }
+ }
+ cmSystemTools::CopyFileIfDifferent(filename_tmp, filename);
+ cmSystemTools::RemoveFile(filename_tmp);
+
+ target->AddSource(filename, true);
+ }
+ }
+}
+
void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
cmGeneratorTarget* target,
const std::string& config,
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index f63fe0f..515ffae 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -126,6 +126,7 @@ public:
const std::string& rawFlag) const;
void AddPchDependencies(cmGeneratorTarget* target,
const std::string& config);
+ void AddUnityBuild(cmGeneratorTarget* target, const std::string& config);
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index bebd5c4..002addf 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -41,6 +41,7 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+ this->LocalGenerator->AddUnityBuild(target, this->ConfigName);
this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 4244402..d603dac 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -43,6 +43,7 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+ this->LocalGenerator->AddUnityBuild(target, this->ConfigName);
this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
}
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 556191f..d4045b3 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -26,6 +26,7 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+ this->LocalGenerator->AddUnityBuild(target, this->ConfigName);
this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 0e3aa3a..a4e1d61 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -60,6 +60,7 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName());
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+ GetLocalGenerator()->AddUnityBuild(target, this->GetConfigName());
GetLocalGenerator()->AddPchDependencies(target, this->GetConfigName());
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 2a09b43..10ea7dd 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -352,6 +352,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("Swift_MODULE_DIRECTORY");
initProp("VS_JUST_MY_CODE_DEBUGGING");
initProp("DISABLE_PRECOMPILE_HEADERS");
+ initProp("UNITY_BUILD");
+ initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_GENERATE_SCHEME");