diff options
author | Brad King <brad.king@kitware.com> | 2019-09-05 12:35:29 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-09-05 12:36:06 (GMT) |
commit | ac4d6d4a9d9b81773e61c643169cb2afe1bab644 (patch) | |
tree | 7679958f3ffece7ae00993fa7c26c70d9b6a1dc2 /Source | |
parent | fcba9c3baa00631407f493f97afe7e9cd1b844a7 (diff) | |
parent | 7786a05c707dc5ffe9fdf7a6b468f56ed18c9e8a (diff) | |
download | CMake-ac4d6d4a9d9b81773e61c643169cb2afe1bab644.zip CMake-ac4d6d4a9d9b81773e61c643169cb2afe1bab644.tar.gz CMake-ac4d6d4a9d9b81773e61c643169cb2afe1bab644.tar.bz2 |
Merge topic 'unity-build'
7786a05c70 Unity build: Add XCode support
1353802af3 Unity build: Add unit tests
8dfeb5d278 Unity build: Add support for Visual Studio generator
7114c141e2 Unity build: Add support for Ninja and Makefile generators
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Stanislav Ershov <digital.stream.of.mind@gmail.com>
Acked-by: Evgeniy Dushistov <dushistov@mail.ru>
Acked-by: Viktor Kirilov <vik.kirilov@gmail.com>
Merge-request: !3611
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 96 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 8 | ||||
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmMakefileUtilityTargetGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 2 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 51 |
10 files changed, 161 insertions, 2 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 427ab44..74d97e1 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2839,6 +2839,7 @@ bool cmGlobalXCodeGenerator::CreateGroups( continue; } + generator->AddUnityBuild(gtgt, ""); generator->AddPchDependencies(gtgt, ""); auto addSourceToGroup = [this, mf, gtgt, diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index f0145c5..e2402ad 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -38,6 +38,7 @@ #include <algorithm> #include <assert.h> +#include <cstdlib> #include <functional> #include <initializer_list> #include <iterator> @@ -2199,6 +2200,101 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target, } } +void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target, + const std::string& config) +{ + if (!target->GetPropertyAsBool("UNITY_BUILD")) { + return; + } + + const std::string buildType = cmSystemTools::UpperCase(config); + + std::string filename_base = + cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", + target->GetName(), ".dir/Unity/"); + + std::vector<cmSourceFile*> sources; + target->GetSourceFiles(sources, buildType); + + auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE"); + const size_t unityBatchSize = + static_cast<size_t>(std::atoi(batchSizeString)); + + auto beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE"); + auto afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE"); + + 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) { + return sf->GetLanguage() == lang && + !sf->GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION") && + !sf->GetPropertyAsBool("GENERATED") && + !sf->GetProperty("COMPILE_OPTIONS") && + !sf->GetProperty("COMPILE_DEFINITIONS") && + !sf->GetProperty("COMPILE_FLAGS") && + !sf->GetProperty("INCLUDE_DIRECTORIES"); + }); + + size_t batchSize = unityBatchSize; + if (unityBatchSize == 0) { + batchSize = filtered_sources.size(); + } + + for (size_t itemsLeft = filtered_sources.size(), chunk = batchSize, + batch = 0; + itemsLeft > 0; itemsLeft -= chunk, ++batch) { + + chunk = std::min(itemsLeft, batchSize); + + std::string filename = cmStrCat(filename_base, "unity_", batch, + (lang == "C") ? ".c" : ".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]; + + // Only in Visual Studio generator we keep the source files + // for explicit processing. For the rest the source files will + // not be included in the project. + if (!this->GetGlobalGenerator()->IsMultiConfig() || + this->GetGlobalGenerator()->IsXcode()) { + sf->SetProperty("HEADER_FILE_ONLY", "ON"); + } + sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str()); + + if (beforeInclude) { + file << beforeInclude << "\n"; + } + + file << "#include \"" << sf->GetFullPath() << "\"\n"; + + if (afterInclude) { + file << afterInclude << "\n"; + } + } + } + cmSystemTools::CopyFileIfDifferent(filename_tmp, filename); + 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()); + } + } +} + void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target, const std::string& config, diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index f63fe0f..515ffae 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -126,6 +126,7 @@ public: const std::string& rawFlag) const; void AddPchDependencies(cmGeneratorTarget* target, const std::string& config); + void AddUnityBuild(cmGeneratorTarget* target, const std::string& config); void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target, const std::string& config, const std::string& lang); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 357ccc8..74f4777 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1321,6 +1321,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, const std::string& libName, cmGeneratorTarget* target) { + this->AddUnityBuild(target, ""); this->AddPchDependencies(target, ""); std::vector<std::string> configs; @@ -1509,8 +1510,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; } diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index bebd5c4..002addf 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -41,6 +41,7 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator( cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->LocalGenerator->AddUnityBuild(target, this->ConfigName); this->LocalGenerator->AddPchDependencies(target, this->ConfigName); } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 4244402..d603dac 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -43,6 +43,7 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator( cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->LocalGenerator->AddUnityBuild(target, this->ConfigName); this->LocalGenerator->AddPchDependencies(target, this->ConfigName); } diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index 556191f..d4045b3 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -26,6 +26,7 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator( cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + this->LocalGenerator->AddUnityBuild(target, this->ConfigName); this->LocalGenerator->AddPchDependencies(target, this->ConfigName); } diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 6c23846..bc2506e 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -61,6 +61,7 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator( cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName()); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); + GetLocalGenerator()->AddUnityBuild(target, this->GetConfigName()); GetLocalGenerator()->AddPchDependencies(target, this->GetConfigName()); } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 2a09b43..10ea7dd 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -352,6 +352,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("Swift_MODULE_DIRECTORY"); initProp("VS_JUST_MY_CODE_DEBUGGING"); initProp("DISABLE_PRECOMPILE_HEADERS"); + initProp("UNITY_BUILD"); + initPropValue("UNITY_BUILD_BATCH_SIZE", "8"); #ifdef __APPLE__ if (this->GetGlobalGenerator()->IsXcode()) { initProp("XCODE_GENERATE_SCHEME"); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 06e1798..29ebe02 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -250,6 +250,7 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator( this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() == this->Makefile->GetCurrentBinaryDirectory()); + this->LocalGenerator->AddUnityBuild(target, ""); this->LocalGenerator->AddPchDependencies(target, ""); } @@ -2070,6 +2071,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(); @@ -2168,6 +2180,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); } |