summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-05-11 14:07:56 +0000
committerKitware Robot <kwrobot@kitware.com>2020-05-11 10:08:12 -0400
commitcee7eb8b3ab31a47f60b5d793c88548acef840e3 (patch)
treebcf6be2088c941bd051a2fcfec91a8f8b433ef7c /Source
parentc2460c0e63e965c6315db666af27dc39bd5a0477 (diff)
parent9f4eb352fe1383f740876e3924205be1d4bf897c (diff)
downloadcmake-cee7eb8b3ab31a47f60b5d793c88548acef840e3.tar.gz
Merge topic 'unity_explicit_groups'
9f4eb352fe Unity Builds: Support explicit specification of sources to groups b00585adcc Unity: Refactor implementation to make it easier to extend Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !4716
Diffstat (limited to 'Source')
-rw-r--r--Source/cmLocalGenerator.cxx178
-rw-r--r--Source/cmTarget.cxx1
2 files changed, 135 insertions, 44 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 9aca775fd5..f29c682f80 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2758,6 +2758,120 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
}
+namespace {
+
+inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
+ std::string const& filename)
+{
+ target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
+ sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+}
+
+inline void IncludeFileInUnitySources(cmGeneratedFileStream& unity_file,
+ std::string const& sf_full_path,
+ cmProp beforeInclude,
+ cmProp afterInclude)
+{
+ if (beforeInclude) {
+ unity_file << *beforeInclude << "\n";
+ }
+
+ unity_file << "#include \"" << sf_full_path << "\"\n";
+
+ if (afterInclude) {
+ unity_file << *afterInclude << "\n";
+ }
+}
+
+std::vector<std::string> AddUnityFilesModeAuto(
+ cmGeneratorTarget* target, std::string const& lang,
+ std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+ cmProp afterInclude, std::string const& filename_base, size_t batchSize)
+{
+ if (batchSize == 0) {
+ batchSize = filtered_sources.size();
+ }
+
+ std::vector<std::string> unity_files;
+ for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
+ itemsLeft > 0; itemsLeft -= chunk, ++batch) {
+
+ chunk = std::min(itemsLeft, batchSize);
+
+ std::string filename = cmStrCat(filename_base, "unity_", batch,
+ (lang == "C") ? "_c.c" : "_cxx.cxx");
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ size_t begin = batch * batchSize;
+ size_t end = begin + chunk;
+
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ target->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+
+ for (; begin != end; ++begin) {
+ cmSourceFile* sf = filtered_sources[begin];
+ RegisterUnitySources(target, sf, filename);
+ IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+ afterInclude);
+ }
+ }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ unity_files.emplace_back(std::move(filename));
+ }
+ return unity_files;
+}
+
+std::vector<std::string> AddUnityFilesModeGroup(
+ cmGeneratorTarget* target, std::string const& lang,
+ std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+ cmProp afterInclude, std::string const& filename_base)
+{
+ std::vector<std::string> unity_files;
+
+ // sources organized by group name. Drop any source
+ // without a group
+ std::unordered_map<std::string, std::vector<cmSourceFile*>> explicit_mapping;
+ for (cmSourceFile* sf : filtered_sources) {
+ if (cmProp value = sf->GetProperty("UNITY_GROUP")) {
+ auto i = explicit_mapping.find(*value);
+ if (i == explicit_mapping.end()) {
+ std::vector<cmSourceFile*> sources{ sf };
+ explicit_mapping.emplace(*value, sources);
+ } else {
+ i->second.emplace_back(sf);
+ }
+ }
+ }
+
+ for (auto const& item : explicit_mapping) {
+ auto const& name = item.first;
+ std::string filename = cmStrCat(filename_base, "unity_", name,
+ (lang == "C") ? "_c.c" : "_cxx.cxx");
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ target->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
+
+ for (cmSourceFile* sf : item.second) {
+ RegisterUnitySources(target, sf, filename);
+ IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+ afterInclude);
+ }
+ }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ unity_files.emplace_back(std::move(filename));
+ }
+
+ return unity_files;
+}
+}
+
void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
{
if (!target->GetPropertyAsBool("UNITY_BUILD")) {
@@ -2786,6 +2900,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
cmProp beforeInclude =
target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
cmProp afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+ cmProp unityMode = target->GetProperty("UNITY_BUILD_MODE");
for (std::string lang : { "C", "CXX" }) {
std::vector<cmSourceFile*> filtered_sources;
@@ -2800,53 +2915,28 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
!sf->GetProperty("INCLUDE_DIRECTORIES");
});
- size_t batchSize = unityBatchSize;
- if (unityBatchSize == 0) {
- batchSize = filtered_sources.size();
+ std::vector<std::string> unity_files;
+ if (!unityMode || *unityMode == "BATCH") {
+ unity_files =
+ AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude,
+ afterInclude, filename_base, unityBatchSize);
+ } else if (unityMode && *unityMode == "GROUP") {
+ unity_files =
+ AddUnityFilesModeGroup(target, lang, filtered_sources, beforeInclude,
+ afterInclude, filename_base);
+ } else {
+ // unity mode is set to an unsupported value
+ std::string e("Invalid UNITY_BUILD_MODE value of " + *unityMode +
+ " assigned to target " + target->GetName() +
+ ". Acceptable values are BATCH and GROUP.");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
}
- for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
- itemsLeft > 0; itemsLeft -= chunk, ++batch) {
-
- chunk = std::min(itemsLeft, batchSize);
-
- std::string filename = cmStrCat(filename_base, "unity_", batch,
- (lang == "C") ? "_c.c" : "_cxx.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];
-
- target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
- sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
-
- if (beforeInclude) {
- file << *beforeInclude << "\n";
- }
-
- file << "#include \"" << sf->ResolveFullPath() << "\"\n";
-
- if (afterInclude) {
- file << *afterInclude << "\n";
- }
- }
- }
- cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
-
- target->AddSource(filename, true);
-
- auto unity = this->Makefile->GetOrCreateSource(filename);
+ for (auto const& file : unity_files) {
+ auto unity = this->GetMakefile()->GetOrCreateSource(file);
+ target->AddSource(file, true);
unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
- unity->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+ unity->SetProperty("UNITY_SOURCE_FILE", file.c_str());
}
}
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index a776398857..d43fbe5c03 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -372,6 +372,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("DISABLE_PRECOMPILE_HEADERS");
initProp("UNITY_BUILD");
initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
+ initPropValue("UNITY_BUILD_MODE", "BATCH");
initPropValue("PCH_WARN_INVALID", "ON");
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {