mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-04 13:19:51 -05:00
Unity build: Add support for Ninja and Makefile generators
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user