|
|
@@ -2808,7 +2808,7 @@ inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
|
|
|
}
|
|
|
|
|
|
cmLocalGenerator::UnitySource cmLocalGenerator::WriteUnitySource(
|
|
|
- cmGeneratorTarget* target,
|
|
|
+ cmGeneratorTarget* target, std::vector<std::string> const& configs,
|
|
|
cmRange<std::vector<UnityBatchedSource>::const_iterator> sources,
|
|
|
cmValue beforeInclude, cmValue afterInclude, std::string filename) const
|
|
|
{
|
|
|
@@ -2818,21 +2818,36 @@ cmLocalGenerator::UnitySource cmLocalGenerator::WriteUnitySource(
|
|
|
file.SetCopyIfDifferent(true);
|
|
|
file << "/* generated by CMake */\n\n";
|
|
|
|
|
|
+ bool perConfig = false;
|
|
|
for (UnityBatchedSource const& ubs : sources) {
|
|
|
+ cm::optional<std::string> cond;
|
|
|
+ if (ubs.Configs.size() != configs.size()) {
|
|
|
+ perConfig = true;
|
|
|
+ cond = std::string();
|
|
|
+ cm::string_view sep;
|
|
|
+ for (size_t ci : ubs.Configs) {
|
|
|
+ cond = cmStrCat(*cond, sep, "defined(CMAKE_UNITY_CONFIG_",
|
|
|
+ cmSystemTools::UpperCase(configs[ci]), ")");
|
|
|
+ sep = " || "_s;
|
|
|
+ }
|
|
|
+ }
|
|
|
RegisterUnitySources(target, ubs.Source, filename);
|
|
|
- WriteUnitySourceInclude(file, ubs.Source->ResolveFullPath(), beforeInclude,
|
|
|
- afterInclude, uniqueIdName);
|
|
|
+ WriteUnitySourceInclude(file, cond, ubs.Source->ResolveFullPath(),
|
|
|
+ beforeInclude, afterInclude, uniqueIdName);
|
|
|
}
|
|
|
|
|
|
- return UnitySource(std::move(filename));
|
|
|
+ return UnitySource(std::move(filename), perConfig);
|
|
|
}
|
|
|
|
|
|
-void cmLocalGenerator::WriteUnitySourceInclude(std::ostream& unity_file,
|
|
|
- std::string const& sf_full_path,
|
|
|
- cmValue beforeInclude,
|
|
|
- cmValue afterInclude,
|
|
|
- cmValue uniqueIdName) const
|
|
|
+void cmLocalGenerator::WriteUnitySourceInclude(
|
|
|
+ std::ostream& unity_file, cm::optional<std::string> const& cond,
|
|
|
+ std::string const& sf_full_path, cmValue beforeInclude, cmValue afterInclude,
|
|
|
+ cmValue uniqueIdName) const
|
|
|
{
|
|
|
+ if (cond) {
|
|
|
+ unity_file << "#if " << *cond << "\n";
|
|
|
+ }
|
|
|
+
|
|
|
if (cmNonempty(uniqueIdName)) {
|
|
|
std::string pathToHash;
|
|
|
auto PathEqOrSubDir = [](std::string const& a, std::string const& b) {
|
|
|
@@ -2867,12 +2882,16 @@ void cmLocalGenerator::WriteUnitySourceInclude(std::ostream& unity_file,
|
|
|
if (afterInclude) {
|
|
|
unity_file << *afterInclude << "\n";
|
|
|
}
|
|
|
+ if (cond) {
|
|
|
+ unity_file << "#endif\n";
|
|
|
+ }
|
|
|
unity_file << "\n";
|
|
|
}
|
|
|
|
|
|
std::vector<cmLocalGenerator::UnitySource>
|
|
|
cmLocalGenerator::AddUnityFilesModeAuto(
|
|
|
cmGeneratorTarget* target, std::string const& lang,
|
|
|
+ std::vector<std::string> const& configs,
|
|
|
std::vector<UnityBatchedSource> const& filtered_sources,
|
|
|
cmValue beforeInclude, cmValue afterInclude,
|
|
|
std::string const& filename_base, size_t batchSize)
|
|
|
@@ -2891,9 +2910,9 @@ cmLocalGenerator::AddUnityFilesModeAuto(
|
|
|
(lang == "C") ? "_c.c" : "_cxx.cxx");
|
|
|
auto const begin = filtered_sources.begin() + batch * batchSize;
|
|
|
auto const end = begin + chunk;
|
|
|
- unity_files.emplace_back(
|
|
|
- this->WriteUnitySource(target, cmMakeRange(begin, end), beforeInclude,
|
|
|
- afterInclude, std::move(filename)));
|
|
|
+ unity_files.emplace_back(this->WriteUnitySource(
|
|
|
+ target, configs, cmMakeRange(begin, end), beforeInclude, afterInclude,
|
|
|
+ std::move(filename)));
|
|
|
}
|
|
|
return unity_files;
|
|
|
}
|
|
|
@@ -2901,6 +2920,7 @@ cmLocalGenerator::AddUnityFilesModeAuto(
|
|
|
std::vector<cmLocalGenerator::UnitySource>
|
|
|
cmLocalGenerator::AddUnityFilesModeGroup(
|
|
|
cmGeneratorTarget* target, std::string const& lang,
|
|
|
+ std::vector<std::string> const& configs,
|
|
|
std::vector<UnityBatchedSource> const& filtered_sources,
|
|
|
cmValue beforeInclude, cmValue afterInclude,
|
|
|
std::string const& filename_base)
|
|
|
@@ -2927,9 +2947,9 @@ cmLocalGenerator::AddUnityFilesModeGroup(
|
|
|
auto const& name = item.first;
|
|
|
std::string filename = cmStrCat(filename_base, "unity_", name,
|
|
|
(lang == "C") ? "_c.c" : "_cxx.cxx");
|
|
|
- unity_files.emplace_back(
|
|
|
- this->WriteUnitySource(target, cmMakeRange(item.second), beforeInclude,
|
|
|
- afterInclude, std::move(filename)));
|
|
|
+ unity_files.emplace_back(this->WriteUnitySource(
|
|
|
+ target, configs, cmMakeRange(item.second), beforeInclude, afterInclude,
|
|
|
+ std::move(filename)));
|
|
|
}
|
|
|
|
|
|
return unity_files;
|
|
|
@@ -2943,19 +2963,24 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
|
|
|
|
|
|
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");
|
|
|
- }
|
|
|
+ std::vector<std::string> configs =
|
|
|
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
|
|
|
+
|
|
|
+ std::map<cmSourceFile const*, size_t> index;
|
|
|
|
|
|
+ for (size_t ci = 0; ci < configs.size(); ++ci) {
|
|
|
// FIXME: Refactor collection of sources to not evaluate object libraries.
|
|
|
std::vector<cmSourceFile*> sources;
|
|
|
- target->GetSourceFiles(sources, config);
|
|
|
-
|
|
|
+ target->GetSourceFiles(sources, configs[ci]);
|
|
|
for (cmSourceFile* sf : sources) {
|
|
|
- unitySources.emplace_back(sf);
|
|
|
+ auto mi = index.find(sf);
|
|
|
+ if (mi == index.end()) {
|
|
|
+ unitySources.emplace_back(sf);
|
|
|
+ std::map<cmSourceFile const*, size_t>::value_type entry(
|
|
|
+ sf, unitySources.size() - 1);
|
|
|
+ mi = index.insert(entry).first;
|
|
|
+ }
|
|
|
+ unitySources[mi->second].Configs.emplace_back(ci);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -2990,13 +3015,13 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
|
|
|
|
|
|
std::vector<UnitySource> unity_files;
|
|
|
if (!unityMode || *unityMode == "BATCH") {
|
|
|
- unity_files =
|
|
|
- AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude,
|
|
|
- afterInclude, filename_base, unityBatchSize);
|
|
|
+ unity_files = AddUnityFilesModeAuto(
|
|
|
+ target, lang, configs, filtered_sources, beforeInclude, afterInclude,
|
|
|
+ filename_base, unityBatchSize);
|
|
|
} else if (unityMode && *unityMode == "GROUP") {
|
|
|
unity_files =
|
|
|
- AddUnityFilesModeGroup(target, lang, filtered_sources, beforeInclude,
|
|
|
- afterInclude, filename_base);
|
|
|
+ AddUnityFilesModeGroup(target, lang, configs, 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 +
|
|
|
@@ -3010,6 +3035,10 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
|
|
|
target->AddSource(file.Path, true);
|
|
|
unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
|
|
|
unity->SetProperty("UNITY_SOURCE_FILE", file.Path);
|
|
|
+ if (file.PerConfig) {
|
|
|
+ unity->SetProperty("COMPILE_DEFINITIONS",
|
|
|
+ "CMAKE_UNITY_CONFIG_$<UPPER_CASE:$<CONFIG>>");
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|