diff options
author | Brad King <brad.king@kitware.com> | 2020-05-11 14:07:56 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-05-11 14:08:12 (GMT) |
commit | cee7eb8b3ab31a47f60b5d793c88548acef840e3 (patch) | |
tree | bcf6be2088c941bd051a2fcfec91a8f8b433ef7c /Source | |
parent | c2460c0e63e965c6315db666af27dc39bd5a0477 (diff) | |
parent | 9f4eb352fe1383f740876e3924205be1d4bf897c (diff) | |
download | CMake-cee7eb8b3ab31a47f60b5d793c88548acef840e3.zip CMake-cee7eb8b3ab31a47f60b5d793c88548acef840e3.tar.gz CMake-cee7eb8b3ab31a47f60b5d793c88548acef840e3.tar.bz2 |
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.cxx | 178 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 1 |
2 files changed, 135 insertions, 44 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9aca775..f29c682 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 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()) { |