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/cmLocalGenerator.cxx | |
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/cmLocalGenerator.cxx')
-rw-r--r-- | Source/cmLocalGenerator.cxx | 96 |
1 files changed, 96 insertions, 0 deletions
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, |