diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmLocalGenerator.cxx | 67 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 1 |
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()) { |