summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorRobert Maynard <robert.maynard@kitware.com>2020-05-06 19:45:42 (GMT)
committerRobert Maynard <robert.maynard@kitware.com>2020-05-07 15:13:34 (GMT)
commit9f4eb352fe1383f740876e3924205be1d4bf897c (patch)
tree6911d23d9c5f950860a9ba1d0048b4d7f1417f1c /Source
parentb00585adcc11afcf4d02d9d9927a929f33b19546 (diff)
downloadCMake-9f4eb352fe1383f740876e3924205be1d4bf897c.zip
CMake-9f4eb352fe1383f740876e3924205be1d4bf897c.tar.gz
CMake-9f4eb352fe1383f740876e3924205be1d4bf897c.tar.bz2
Unity Builds: Support explicit specification of sources to groups
Instead of having CMake determine which files should go into each unity file, the user can now use explicitly state the mapping.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmLocalGenerator.cxx67
-rw-r--r--Source/cmTarget.cxx1
2 files changed, 65 insertions, 3 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index dee5cb4..63b7578 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2821,6 +2821,53 @@ std::vector<std::string> AddUnityFilesModeAuto(
}
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)
@@ -2851,6 +2898,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;
@@ -2865,9 +2913,22 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
!sf->GetProperty("INCLUDE_DIRECTORIES");
});
- std::vector<std::string> unity_files =
- AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude,
- afterInclude, filename_base, unityBatchSize);
+ 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 (auto const& file : unity_files) {
auto unity = this->GetMakefile()->GetOrCreateSource(file);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index a776398..d43fbe5 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()) {