Unity build: Add support for Visual Studio generator

It works as expected in Visual Studio.

Visual Studio 2017 will (partially) benefit from the build in
support for unity builds. The custom unity sources are used, because
the build in support doesn't allow batching of certain number of
files. It can do only batching by directory.
This commit is contained in:
Cristian Adam 2019-07-29 17:44:55 +02:00
parent 7114c141e2
commit 8dfeb5d278
3 changed files with 65 additions and 3 deletions

View File

@ -2266,7 +2266,10 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target,
for (; begin != end; ++begin) {
cmSourceFile* sf = filtered_sources[begin];
sf->SetProperty("HEADER_FILE_ONLY", "ON");
if (!this->GetGlobalGenerator()->IsMultiConfig()) {
sf->SetProperty("HEADER_FILE_ONLY", "ON");
}
sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
if (beforeInclude) {
file << beforeInclude << "\n";
@ -2283,6 +2286,10 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target,
cmSystemTools::RemoveFile(filename_tmp);
target->AddSource(filename, true);
auto unity = this->Makefile->GetOrCreateSource(filename);
unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
unity->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
}
}
}

View File

@ -1320,6 +1320,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
const std::string& libName,
cmGeneratorTarget* target)
{
this->AddUnityBuild(target, "");
this->AddPchDependencies(target, "");
std::vector<std::string> configs;
@ -1508,8 +1509,11 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
const std::string& linkLanguage = gt->GetLinkerLanguage(config.c_str());
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
fc.ExcludedFromBuild =
sf.GetPropertyAsBool("HEADER_FILE_ONLY") || !cmContains(acs.Configs, ci);
fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
!cmContains(acs.Configs, ci) ||
(gt->GetPropertyAsBool("UNITY_BUILD") &&
sf.GetProperty("UNITY_SOURCE_FILE") &&
!sf.GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION"));
if (fc.ExcludedFromBuild) {
needfc = true;
}

View File

@ -250,6 +250,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
this->Makefile->GetCurrentBinaryDirectory());
this->LocalGenerator->AddUnityBuild(target, "");
this->LocalGenerator->AddPchDependencies(target, "");
}
@ -2049,6 +2050,17 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) {
return;
}
const bool haveUnityBuild =
this->GeneratorTarget->GetPropertyAsBool("UNITY_BUILD");
if (haveUnityBuild &&
this->GlobalGenerator->GetVersion() >=
cmGlobalVisualStudioGenerator::VS15) {
Elem e1(e0, "PropertyGroup");
e1.Element("EnableUnitySupport", "true");
}
Elem e1(e0, "ItemGroup");
e1.SetHasElements();
@ -2147,6 +2159,45 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
Elem e2(e1, tool);
this->WriteSource(e2, si.Source);
bool useNativeUnityBuild = false;
if (haveUnityBuild &&
this->GlobalGenerator->GetVersion() >=
cmGlobalVisualStudioGenerator::VS15) {
// Magic value taken from cmGlobalVisualStudioVersionedGenerator.cxx
static const std::string vs15 = "141";
std::string toolset =
this->GlobalGenerator->GetPlatformToolsetString();
cmSystemTools::ReplaceString(toolset, "v", "");
if (toolset.empty() ||
cmSystemTools::VersionCompareGreaterEq(toolset, vs15)) {
useNativeUnityBuild = true;
}
}
if (haveUnityBuild && strcmp(tool, "ClCompile") == 0 &&
si.Source->GetProperty("UNITY_SOURCE_FILE")) {
if (useNativeUnityBuild) {
e2.Attribute(
"IncludeInUnityFile",
si.Source->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION")
? "false"
: "true");
e2.Attribute("CustomUnityFile", "true");
std::string unityDir = cmSystemTools::GetFilenamePath(
si.Source->GetProperty("UNITY_SOURCE_FILE"));
e2.Attribute("UnityFilesDirectory", unityDir);
} else {
// Visual Studio versions prior to 2017 do not know about unity
// builds, thus we exclude the files alredy part of unity sources.
if (!si.Source->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION")) {
exclude_configs = si.Configs;
}
}
}
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) {
this->OutputSourceSpecificFlags(e2, si.Source);
}