cmLocalGenerator: Add dedicated types to hold unity source info

This commit is contained in:
Brad King
2021-11-10 11:57:01 -05:00
parent de6e362a88
commit 53990059da
2 changed files with 81 additions and 44 deletions

View File

@@ -2807,9 +2807,9 @@ inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
}
}
std::string cmLocalGenerator::WriteUnitySource(
cmLocalGenerator::UnitySource cmLocalGenerator::WriteUnitySource(
cmGeneratorTarget* target,
cmRange<std::vector<cmSourceFile*>::const_iterator> sources,
cmRange<std::vector<UnityBatchedSource>::const_iterator> sources,
cmValue beforeInclude, cmValue afterInclude, std::string filename) const
{
cmValue uniqueIdName = target->GetProperty("UNITY_BUILD_UNIQUE_ID");
@@ -2817,12 +2817,14 @@ std::string cmLocalGenerator::WriteUnitySource(
filename, false, target->GetGlobalGenerator()->GetMakefileEncoding());
file.SetCopyIfDifferent(true);
file << "/* generated by CMake */\n\n";
for (cmSourceFile* sf : sources) {
RegisterUnitySources(target, sf, filename);
WriteUnitySourceInclude(file, sf->ResolveFullPath(), beforeInclude,
for (UnityBatchedSource const& ubs : sources) {
RegisterUnitySources(target, ubs.Source, filename);
WriteUnitySourceInclude(file, ubs.Source->ResolveFullPath(), beforeInclude,
afterInclude, uniqueIdName);
}
return filename;
return UnitySource(std::move(filename));
}
void cmLocalGenerator::WriteUnitySourceInclude(std::ostream& unity_file,
@@ -2868,16 +2870,18 @@ void cmLocalGenerator::WriteUnitySourceInclude(std::ostream& unity_file,
unity_file << "\n";
}
std::vector<std::string> cmLocalGenerator::AddUnityFilesModeAuto(
std::vector<cmLocalGenerator::UnitySource>
cmLocalGenerator::AddUnityFilesModeAuto(
cmGeneratorTarget* target, std::string const& lang,
std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude,
cmValue afterInclude, std::string const& filename_base, size_t batchSize)
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
std::string const& filename_base, size_t batchSize)
{
if (batchSize == 0) {
batchSize = filtered_sources.size();
}
std::vector<std::string> unity_files;
std::vector<UnitySource> unity_files;
for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
itemsLeft > 0; itemsLeft -= chunk, ++batch) {
@@ -2894,24 +2898,27 @@ std::vector<std::string> cmLocalGenerator::AddUnityFilesModeAuto(
return unity_files;
}
std::vector<std::string> cmLocalGenerator::AddUnityFilesModeGroup(
std::vector<cmLocalGenerator::UnitySource>
cmLocalGenerator::AddUnityFilesModeGroup(
cmGeneratorTarget* target, std::string const& lang,
std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude,
cmValue afterInclude, std::string const& filename_base)
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
std::string const& filename_base)
{
std::vector<std::string> unity_files;
std::vector<UnitySource> 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 (cmValue value = sf->GetProperty("UNITY_GROUP")) {
std::unordered_map<std::string, std::vector<UnityBatchedSource>>
explicit_mapping;
for (UnityBatchedSource const& ubs : filtered_sources) {
if (cmValue value = ubs.Source->GetProperty("UNITY_GROUP")) {
auto i = explicit_mapping.find(*value);
if (i == explicit_mapping.end()) {
std::vector<cmSourceFile*> sources{ sf };
explicit_mapping.emplace(*value, sources);
std::vector<UnityBatchedSource> sources{ ubs };
explicit_mapping.emplace(*value, std::move(sources));
} else {
i->second.emplace_back(sf);
i->second.emplace_back(ubs);
}
}
}
@@ -2934,20 +2941,28 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
return;
}
// FIXME: Handle all configurations in multi-config generators.
std::string config;
if (!this->GetGlobalGenerator()->IsMultiConfig()) {
config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
std::vector<UnityBatchedSource> unitySources;
{
// FIXME: Handle all configurations in multi-config generators.
std::string config;
if (!this->GetGlobalGenerator()->IsMultiConfig()) {
config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
}
// FIXME: Refactor collection of sources to not evaluate object libraries.
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, config);
for (cmSourceFile* sf : sources) {
unitySources.emplace_back(sf);
}
}
std::string filename_base =
cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/",
target->GetName(), ".dir/Unity/");
// FIXME: Refactor collection of sources to not evaluate object libraries.
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, config);
cmValue batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
const size_t unityBatchSize = batchSizeString
? static_cast<size_t>(std::atoi(batchSizeString->c_str()))
@@ -2959,9 +2974,11 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
cmValue unityMode = target->GetProperty("UNITY_BUILD_MODE");
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) {
std::vector<UnityBatchedSource> filtered_sources;
std::copy_if(unitySources.begin(), unitySources.end(),
std::back_inserter(filtered_sources),
[&](UnityBatchedSource const& ubs) -> bool {
cmSourceFile* sf = ubs.Source;
return sf->GetLanguage() == lang &&
!sf->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION") &&
!sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
@@ -2971,7 +2988,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
!sf->GetProperty("INCLUDE_DIRECTORIES");
});
std::vector<std::string> unity_files;
std::vector<UnitySource> unity_files;
if (!unityMode || *unityMode == "BATCH") {
unity_files =
AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude,
@@ -2988,11 +3005,11 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
this->IssueMessage(MessageType::FATAL_ERROR, e);
}
for (auto const& file : unity_files) {
auto* unity = this->GetMakefile()->GetOrCreateSource(file);
target->AddSource(file, true);
for (UnitySource const& file : unity_files) {
auto* unity = this->GetMakefile()->GetOrCreateSource(file.Path);
target->AddSource(file.Path, true);
unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
unity->SetProperty("UNITY_SOURCE_FILE", file);
unity->SetProperty("UNITY_SOURCE_FILE", file.Path);
}
}
}

View File

@@ -11,6 +11,7 @@
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <cm3p/kwiml/int.h>
@@ -660,22 +661,41 @@ private:
cmGeneratorTarget* reuseTarget,
std::vector<std::string> const& extensions);
std::string WriteUnitySource(
struct UnityBatchedSource
{
cmSourceFile* Source = nullptr;
UnityBatchedSource(cmSourceFile* sf)
: Source(sf)
{
}
};
struct UnitySource
{
std::string Path;
UnitySource(std::string path)
: Path(std::move(path))
{
}
};
UnitySource WriteUnitySource(
cmGeneratorTarget* target,
cmRange<std::vector<cmSourceFile*>::const_iterator> sources,
cmRange<std::vector<UnityBatchedSource>::const_iterator> sources,
cmValue beforeInclude, cmValue afterInclude, std::string filename) const;
void WriteUnitySourceInclude(std::ostream& unity_file,
std::string const& sf_full_path,
cmValue beforeInclude, cmValue afterInclude,
cmValue uniqueIdName) const;
std::vector<std::string> AddUnityFilesModeAuto(
std::vector<UnitySource> AddUnityFilesModeAuto(
cmGeneratorTarget* target, std::string const& lang,
std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude,
cmValue afterInclude, std::string const& filename_base, size_t batchSize);
std::vector<std::string> AddUnityFilesModeGroup(
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
std::string const& filename_base, size_t batchSize);
std::vector<UnitySource> AddUnityFilesModeGroup(
cmGeneratorTarget* target, std::string const& lang,
std::vector<cmSourceFile*> const& filtered_sources, cmValue beforeInclude,
cmValue afterInclude, std::string const& filename_base);
std::vector<UnityBatchedSource> const& filtered_sources,
cmValue beforeInclude, cmValue afterInclude,
std::string const& filename_base);
};
#if !defined(CMAKE_BOOTSTRAP)