summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/cpack_gen/archive.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst5
-rw-r--r--Help/manual/cmake-variables.7.rst2
-rw-r--r--Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst7
-rw-r--r--Help/prop_tgt/UNITY_BUILD.rst55
-rw-r--r--Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst13
-rw-r--r--Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst8
-rw-r--r--Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst8
-rw-r--r--Help/release/dev/cpack-zstd.rst5
-rw-r--r--Help/release/dev/unity-build.rst6
-rw-r--r--Help/variable/CMAKE_UNITY_BUILD.rst6
-rw-r--r--Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst6
-rw-r--r--Source/CMakeLists.txt6
-rw-r--r--Source/CPack/cmCPack7zGenerator.cxx13
-rw-r--r--Source/CPack/cmCPack7zGenerator.h29
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx51
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h23
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.cxx1
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.h6
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.h6
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx16
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.h2
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx42
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.h7
-rw-r--r--Source/CPack/cmCPackTGZGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackTGZGenerator.h29
-rw-r--r--Source/CPack/cmCPackTXZGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackTXZGenerator.h29
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.cxx13
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.h28
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.h28
-rw-r--r--Source/CPack/cmCPackZIPGenerator.cxx13
-rw-r--r--Source/CPack/cmCPackZIPGenerator.h29
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx1
-rw-r--r--Source/cmLocalGenerator.cxx96
-rw-r--r--Source/cmLocalGenerator.h1
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx8
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx1
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx1
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx1
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx1
-rw-r--r--Source/cmTarget.cxx2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx51
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/UnityBuild/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/UnityBuild/RunCMakeTest.cmake23
-rw-r--r--Tests/RunCMake/UnityBuild/func.c6
-rw-r--r--Tests/RunCMake/UnityBuild/func.h6
-rw-r--r--Tests/RunCMake/UnityBuild/main.c6
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_batchsize-check.cmake11
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_batchsize.cmake16
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c-check.cmake5
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c.cmake12
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx-check.cmake11
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx.cmake17
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build-check.cmake5
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build.cmake10
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include-check.cmake7
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include.cmake13
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_cxx-check.cmake5
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_cxx.cmake12
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_default_batchsize-check.cmake7
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_default_batchsize.cmake15
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake7
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_order.cmake12
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake8
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake14
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_skip.cmake30
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildNative-check.cmake45
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildNative.cmake12
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildPre2017-check.cmake48
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildPre2017.cmake12
76 files changed, 777 insertions, 322 deletions
diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst
index b288aad..d455f4b 100644
--- a/Help/cpack_gen/archive.rst
+++ b/Help/cpack_gen/archive.rst
@@ -9,6 +9,7 @@ different formats:
- TGZ (.tar.gz)
- TXZ (.tar.xz)
- TZ (.tar.Z)
+ - TZST (.tar.zst)
- ZIP (.zip)
Variables specific to CPack Archive generator
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 25d6b24..19afb7d 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -323,6 +323,10 @@ Properties on Targets
/prop_tgt/Swift_MODULE_DIRECTORY
/prop_tgt/Swift_MODULE_NAME
/prop_tgt/TYPE
+ /prop_tgt/UNITY_BUILD
+ /prop_tgt/UNITY_BUILD_BATCH_SIZE
+ /prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE
+ /prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE
/prop_tgt/VERSION
/prop_tgt/VISIBILITY_INLINES_HIDDEN
/prop_tgt/VS_CONFIGURATION_TYPE
@@ -450,6 +454,7 @@ Properties on Source Files
/prop_sf/SKIP_AUTORCC
/prop_sf/SKIP_AUTOUIC
/prop_sf/SKIP_PRECOMPILE_HEADERS
+ /prop_sf/SKIP_UNITY_BUILD_INCLUSION
/prop_sf/Swift_DEPENDENCIES_FILE
/prop_sf/Swift_DIAGNOSTICS_FILE
/prop_sf/SYMBOLIC
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 08e2de4..2d473d8 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -432,6 +432,8 @@ Variables that Control the Build
/variable/CMAKE_TRY_COMPILE_CONFIGURATION
/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
/variable/CMAKE_TRY_COMPILE_TARGET_TYPE
+ /variable/CMAKE_UNITY_BUILD
+ /variable/CMAKE_UNITY_BUILD_BATCH_SIZE
/variable/CMAKE_USE_RELATIVE_PATHS
/variable/CMAKE_VISIBILITY_INLINES_HIDDEN
/variable/CMAKE_VS_GLOBALS
diff --git a/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst b/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
new file mode 100644
index 0000000..53f3970
--- /dev/null
+++ b/Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst
@@ -0,0 +1,7 @@
+SKIP_UNITY_BUILD_INCLUSION
+--------------------------
+
+Is this source file skipped by :prop_tgt:`UNITY_BUILD` feature.
+
+This property helps with "ODR (One definition rule)" problems
+that one would run into when using an :prop_tgt:`UNITY_BUILD`.
diff --git a/Help/prop_tgt/UNITY_BUILD.rst b/Help/prop_tgt/UNITY_BUILD.rst
new file mode 100644
index 0000000..d326ee2
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD.rst
@@ -0,0 +1,55 @@
+UNITY_BUILD
+-----------
+
+Should the target source files be processed into batches for
+faster compilation. This feature is known as "Unity build",
+or "Jumbo build".
+
+The `C` and `CXX` source files are grouped separately.
+
+This property is initialized by the value of the
+:variable:`CMAKE_UNITY_BUILD` variable if it is set when
+a target is created.
+
+.. note ::
+
+ It's not recommended to directly set :prop_tgt:`UNITY_BUILD`
+ to `ON`, but to instead set :variable:`CMAKE_UNITY_BUILD` from
+ the command line. However, it IS recommended to set
+ :prop_tgt:`UNITY_BUILD` to `OFF` if you need to ensure that a
+ target doesn't get a unity build.
+
+The batch size can be specified by setting
+:prop_tgt:`UNITY_BUILD_BATCH_SIZE`.
+
+The batching of source files is done by adding new sources files
+wich will `#include` the source files, and exclude them from
+building by setting :prop_sf:`HEADER_FILE_ONLY` to `ON`.
+
+
+ODR (One definition rule) errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Since multiple source files are included into one source file,
+it can lead to ODR errors. This section contains properites
+which help fixing these errors.
+
+The source files marked by :prop_sf:`GENERATED` will be skipped
+from unity build. This applies also for the source files marked
+with :prop_sf:`SKIP_UNITY_BUILD_INCLUSION`.
+
+The source files that have :prop_sf:`COMPILE_OPTIONS`,
+:prop_sf:`COMPILE_DEFINITIONS`, :prop_sf:`COMPILE_FLAGS`, or
+:prop_sf:`INCLUDE_DIRECTORIES` will also be skipped.
+
+With the :prop_tgt:`UNITY_BUILD_CODE_BEFORE_INCLUDE` and
+:prop_tgt:`UNITY_BUILD_CODE_AFTER_INCLUDE` one can specify code
+to be injected in the unity source file before and after every
+`#include` statement.
+
+.. note ::
+
+ The order of source files defined in the `CMakeLists.txt` will
+ be preserved into the generated unity source files. This can
+ be used to manually enforce a specific grouping based on the
+ :prop_tgt:`UNITY_BUILD_BATCH_SIZE`.
diff --git a/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst b/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
new file mode 100644
index 0000000..2426689
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD_BATCH_SIZE.rst
@@ -0,0 +1,13 @@
+UNITY_BUILD_BATCH_SIZE
+----------------------
+
+Specifies how many source code files will be included into a
+:prop_tgt:`UNITY_BUILD` source file.
+
+If the property is not set, CMake will use the value provided
+by :variable:`CMAKE_UNITY_BUILD_BATCH_SIZE`.
+
+By setting it to value `0` the generated unity source file will
+contain all the source files that would be otherwise be split
+into multiple batches. It is not recommended to do so, since it
+would affect performance.
diff --git a/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst b/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
new file mode 100644
index 0000000..7795289
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE.rst
@@ -0,0 +1,8 @@
+UNITY_BUILD_CODE_AFTER_INCLUDE
+------------------------------
+
+Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
+feature just after the `#include` statement of the targeted source
+files.
+
+This could be something like `#undef NOMINMAX`.
diff --git a/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst b/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
new file mode 100644
index 0000000..f335463
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE.rst
@@ -0,0 +1,8 @@
+UNITY_BUILD_CODE_BEFORE_INCLUDE
+-------------------------------
+
+Code snippet which is included verbatim by the :prop_tgt:`UNITY_BUILD`
+feature just before the `#include` statement of the targeted source
+files.
+
+This could be something like `#define NOMINMAX`.
diff --git a/Help/release/dev/cpack-zstd.rst b/Help/release/dev/cpack-zstd.rst
new file mode 100644
index 0000000..e1e64a2
--- /dev/null
+++ b/Help/release/dev/cpack-zstd.rst
@@ -0,0 +1,5 @@
+cpack-zstd
+----------
+
+* The :cpack_gen:`CPack Archive Generator` learned to generate `.tar.zst`
+ packages with Zstandard compression.
diff --git a/Help/release/dev/unity-build.rst b/Help/release/dev/unity-build.rst
new file mode 100644
index 0000000..293a375
--- /dev/null
+++ b/Help/release/dev/unity-build.rst
@@ -0,0 +1,6 @@
+Unity build
+-----------
+
+* The :prop_tgt:`UNITY_BUILD` target property was added to tell
+ generators to batch include source files for faster compilation
+ times.
diff --git a/Help/variable/CMAKE_UNITY_BUILD.rst b/Help/variable/CMAKE_UNITY_BUILD.rst
new file mode 100644
index 0000000..3096954
--- /dev/null
+++ b/Help/variable/CMAKE_UNITY_BUILD.rst
@@ -0,0 +1,6 @@
+CMAKE_UNITY_BUILD
+-----------------
+
+Default value for :prop_tgt:`UNITY_BUILD` of targets.
+
+By default ``CMAKE_UNITY_BUILD`` is ``OFF``.
diff --git a/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst b/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
new file mode 100644
index 0000000..3ab2344
--- /dev/null
+++ b/Help/variable/CMAKE_UNITY_BUILD_BATCH_SIZE.rst
@@ -0,0 +1,6 @@
+CMAKE_UNITY_BUILD_BATCH_SIZE
+----------------------------
+
+Default value for :prop_tgt:`UNITY_BUILD_BATCH_SIZE` of targets.
+
+By default ``CMAKE_UNITY_BUILD_BATCH_SIZE`` is set to ``8``.
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 2ff6c8c..decb39a 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -978,12 +978,6 @@ set(CPACK_SRCS
CPack/cmCPackNSISGenerator.cxx
CPack/cmCPackNuGetGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
- CPack/cmCPackTGZGenerator.cxx
- CPack/cmCPackTXZGenerator.cxx
- CPack/cmCPackTarBZip2Generator.cxx
- CPack/cmCPackTarCompressGenerator.cxx
- CPack/cmCPackZIPGenerator.cxx
- CPack/cmCPack7zGenerator.cxx
)
# CPack IFW generator
set(CPACK_SRCS ${CPACK_SRCS}
diff --git a/Source/CPack/cmCPack7zGenerator.cxx b/Source/CPack/cmCPack7zGenerator.cxx
deleted file mode 100644
index 7413770..0000000
--- a/Source/CPack/cmCPack7zGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPack7zGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPack7zGenerator::cmCPack7zGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "7zip")
-{
-}
-
-cmCPack7zGenerator::~cmCPack7zGenerator() = default;
diff --git a/Source/CPack/cmCPack7zGenerator.h b/Source/CPack/cmCPack7zGenerator.h
deleted file mode 100644
index 8af4c4a..0000000
--- a/Source/CPack/cmCPack7zGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPack7zGenerator_h
-#define cmCPack7zGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPack7zGenerator
- * \brief A generator for 7z files
- */
-class cmCPack7zGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPack7zGenerator, cmCPackArchiveGenerator);
-
- /**
- * Construct generator
- */
- cmCPack7zGenerator();
- ~cmCPack7zGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".7z"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 6c9c6b9..1271b08 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -16,11 +16,54 @@
#include <utility>
#include <vector>
-cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t,
- std::string const& format)
+cmCPackGenerator* cmCPackArchiveGenerator::Create7ZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "7zip",
+ ".7z");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTBZ2Generator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr",
+ ".tar.bz2");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTGZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr",
+ ".tar.gz");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTXZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr",
+ ".tar.xz");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTZGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, "paxr",
+ ".tar.Z");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateTZSTGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressZstd, "paxr",
+ ".tar.zst");
+}
+
+cmCPackGenerator* cmCPackArchiveGenerator::CreateZIPGenerator()
+{
+ return new cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "zip",
+ ".zip");
+}
+
+cmCPackArchiveGenerator::cmCPackArchiveGenerator(
+ cmArchiveWrite::Compress compress, std::string format, std::string extension)
+ : Compress(compress)
+ , ArchiveFormat(std::move(format))
+ , OutputExtension(std::move(extension))
{
- this->Compress = t;
- this->ArchiveFormat = format;
}
cmCPackArchiveGenerator::~cmCPackArchiveGenerator() = default;
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index 9983854..f5be0aa 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -24,10 +24,19 @@ class cmCPackArchiveGenerator : public cmCPackGenerator
public:
typedef cmCPackGenerator Superclass;
+ static cmCPackGenerator* Create7ZGenerator();
+ static cmCPackGenerator* CreateTBZ2Generator();
+ static cmCPackGenerator* CreateTGZGenerator();
+ static cmCPackGenerator* CreateTXZGenerator();
+ static cmCPackGenerator* CreateTZGenerator();
+ static cmCPackGenerator* CreateTZSTGenerator();
+ static cmCPackGenerator* CreateZIPGenerator();
+
/**
* Construct generator
*/
- cmCPackArchiveGenerator(cmArchiveWrite::Compress, std::string const& format);
+ cmCPackArchiveGenerator(cmArchiveWrite::Compress t, std::string format,
+ std::string extension);
~cmCPackArchiveGenerator() override;
// Used to add a header to the archive
virtual int GenerateHeader(std::ostream* os);
@@ -68,9 +77,19 @@ protected:
* components will be put in a single installer.
*/
int PackageComponentsAllInOne();
- const char* GetOutputExtension() override = 0;
+
+private:
+ const char* GetNameOfClass() override { return "cmCPackArchiveGenerator"; }
+
+ const char* GetOutputExtension() override
+ {
+ return this->OutputExtension.c_str();
+ }
+
+private:
cmArchiveWrite::Compress Compress;
std::string ArchiveFormat;
+ std::string OutputExtension;
};
#endif
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
index 553a677..22385055 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmsys/SystemTools.hxx"
cmCPackCygwinBinaryGenerator::cmCPackCygwinBinaryGenerator()
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", ".tar.bz2")
{
}
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.h b/Source/CPack/cmCPackCygwinBinaryGenerator.h
index f87a134..47bd41e 100644
--- a/Source/CPack/cmCPackCygwinBinaryGenerator.h
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.h
@@ -3,15 +3,15 @@
#ifndef cmCPackCygwinBinaryGenerator_h
#define cmCPackCygwinBinaryGenerator_h
-#include "cmCPackTarBZip2Generator.h"
+#include "cmCPackArchiveGenerator.h"
/** \class cmCPackCygwinBinaryGenerator
* \brief A generator for TarBZip2 files
*/
-class cmCPackCygwinBinaryGenerator : public cmCPackTarBZip2Generator
+class cmCPackCygwinBinaryGenerator : public cmCPackArchiveGenerator
{
public:
- cmCPackTypeMacro(cmCPackCygwinBinaryGenerator, cmCPackTarBZip2Generator);
+ cmCPackTypeMacro(cmCPackCygwinBinaryGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
index 8cae9b4..5f6aab0 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
@@ -20,6 +20,7 @@
#endif
cmCPackCygwinSourceGenerator::cmCPackCygwinSourceGenerator()
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr", ".tar.bz2")
{
}
@@ -40,11 +41,8 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
cmStrCat(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), ".tar.bz2");
packageFileNames[0] = packageDirFileName;
std::string output;
- // skip one parent up to the cmCPackTarBZip2Generator
- // to create tar.bz2 file with the list of source
- // files
- this->Compress = cmArchiveWrite::CompressBZip2;
- if (!this->cmCPackTarBZip2Generator::PackageFiles()) {
+ // create tar.bz2 file with the list of source files
+ if (!this->cmCPackArchiveGenerator::PackageFiles()) {
return 0;
}
// Now create a tar file that contains the above .tar.bz2 file
@@ -130,7 +128,7 @@ int cmCPackCygwinSourceGenerator::PackageFiles()
packageFileNames[0] = outerTarFile;
/* update the toplevel dir */
toplevel = tmpDir;
- if (!this->cmCPackTarBZip2Generator::PackageFiles()) {
+ if (!this->cmCPackArchiveGenerator::PackageFiles()) {
return 0;
}
return 1;
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.h b/Source/CPack/cmCPackCygwinSourceGenerator.h
index a909b15..98d8f0a 100644
--- a/Source/CPack/cmCPackCygwinSourceGenerator.h
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.h
@@ -3,15 +3,15 @@
#ifndef cmCPackCygwinSourceGenerator_h
#define cmCPackCygwinSourceGenerator_h
-#include "cmCPackTarBZip2Generator.h"
+#include "cmCPackArchiveGenerator.h"
/** \class cmCPackCygwinSourceGenerator
* \brief A generator for cygwin source files
*/
-class cmCPackCygwinSourceGenerator : public cmCPackTarBZip2Generator
+class cmCPackCygwinSourceGenerator : public cmCPackArchiveGenerator
{
public:
- cmCPackTypeMacro(cmCPackCygwinSourceGenerator, cmCPackTarBZip2Generator);
+ cmCPackTypeMacro(cmCPackCygwinSourceGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index bbba8a1..3979000 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -21,7 +21,7 @@
#include <utility>
cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr")
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr", ".txz")
{
}
@@ -276,12 +276,6 @@ void write_manifest_files(cmGeneratedFileStream& s,
s << " },\n";
}
-static bool has_suffix(const std::string& str, const std::string& suffix)
-{
- return str.size() >= suffix.size() &&
- str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
-}
-
int cmCPackFreeBSDGenerator::PackageFiles()
{
if (!this->ReadListFile("Internal/CPack/CPackFreeBSD.cmake")) {
@@ -327,13 +321,13 @@ int cmCPackFreeBSDGenerator::PackageFiles()
pkg_create_from_manifest(output_dir.c_str(), ::TXZ, toplevel.c_str(),
manifestname.c_str(), nullptr);
- std::string broken_suffix = std::string("-") +
- var_lookup("CPACK_TOPLEVEL_TAG") + std::string(GetOutputExtension());
+ std::string broken_suffix =
+ cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), ".txz");
for (std::string& name : packageFileNames) {
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Packagefile " << name << std::endl);
- if (has_suffix(name, broken_suffix)) {
+ if (cmHasSuffix(name, broken_suffix)) {
name.replace(name.size() - broken_suffix.size(), std::string::npos,
- GetOutputExtension());
+ ".txz");
break;
}
}
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.h b/Source/CPack/cmCPackFreeBSDGenerator.h
index 99d2e24..80c53b1 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.h
+++ b/Source/CPack/cmCPackFreeBSDGenerator.h
@@ -28,8 +28,6 @@ public:
int PackageFiles() override;
protected:
- const char* GetOutputExtension() override { return ".txz"; }
-
std::string var_lookup(const char* var_name);
void write_manifest_fields(cmGeneratedFileStream&);
};
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index 2c5ab4d..4d41049 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -7,10 +7,10 @@
#include "IFW/cmCPackIFWGenerator.h"
#include "cmAlgorithms.h"
-#include "cmCPack7zGenerator.h"
#ifdef HAVE_FREEBSD_PKG
# include "cmCPackFreeBSDGenerator.h"
#endif
+#include "cmCPackArchiveGenerator.h"
#include "cmCPackDebGenerator.h"
#include "cmCPackExternalGenerator.h"
#include "cmCPackGenerator.h"
@@ -18,11 +18,6 @@
#include "cmCPackNSISGenerator.h"
#include "cmCPackNuGetGenerator.h"
#include "cmCPackSTGZGenerator.h"
-#include "cmCPackTGZGenerator.h"
-#include "cmCPackTXZGenerator.h"
-#include "cmCPackTarBZip2Generator.h"
-#include "cmCPackTarCompressGenerator.h"
-#include "cmCPackZIPGenerator.h"
#ifdef __APPLE__
# include "cmCPackBundleGenerator.h"
@@ -48,13 +43,21 @@
cmCPackGeneratorFactory::cmCPackGeneratorFactory()
{
- if (cmCPackTGZGenerator::CanGenerate()) {
+ if (cmCPackArchiveGenerator::CanGenerate()) {
+ this->RegisterGenerator("7Z", "7-Zip file format",
+ cmCPackArchiveGenerator::Create7ZGenerator);
+ this->RegisterGenerator("TBZ2", "Tar BZip2 compression",
+ cmCPackArchiveGenerator::CreateTBZ2Generator);
this->RegisterGenerator("TGZ", "Tar GZip compression",
- cmCPackTGZGenerator::CreateGenerator);
- }
- if (cmCPackTXZGenerator::CanGenerate()) {
+ cmCPackArchiveGenerator::CreateTGZGenerator);
this->RegisterGenerator("TXZ", "Tar XZ compression",
- cmCPackTXZGenerator::CreateGenerator);
+ cmCPackArchiveGenerator::CreateTXZGenerator);
+ this->RegisterGenerator("TZ", "Tar Compress compression",
+ cmCPackArchiveGenerator::CreateTZGenerator);
+ this->RegisterGenerator("TZST", "Tar Zstandard compression",
+ cmCPackArchiveGenerator::CreateTZSTGenerator);
+ this->RegisterGenerator("ZIP", "ZIP file format",
+ cmCPackArchiveGenerator::CreateZIPGenerator);
}
if (cmCPackSTGZGenerator::CanGenerate()) {
this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression",
@@ -80,29 +83,12 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
cmCPackCygwinSourceGenerator::CreateGenerator);
}
#endif
-
- if (cmCPackZIPGenerator::CanGenerate()) {
- this->RegisterGenerator("ZIP", "ZIP file format",
- cmCPackZIPGenerator::CreateGenerator);
- }
- if (cmCPack7zGenerator::CanGenerate()) {
- this->RegisterGenerator("7Z", "7-Zip file format",
- cmCPack7zGenerator::CreateGenerator);
- }
#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_LIBUUID))
if (cmCPackWIXGenerator::CanGenerate()) {
this->RegisterGenerator("WIX", "MSI file format via WiX tools",
cmCPackWIXGenerator::CreateGenerator);
}
#endif
- if (cmCPackTarBZip2Generator::CanGenerate()) {
- this->RegisterGenerator("TBZ2", "Tar BZip2 compression",
- cmCPackTarBZip2Generator::CreateGenerator);
- }
- if (cmCPackTarCompressGenerator::CanGenerate()) {
- this->RegisterGenerator("TZ", "Tar Compress compression",
- cmCPackTarCompressGenerator::CreateGenerator);
- }
if (cmCPackDebGenerator::CanGenerate()) {
this->RegisterGenerator("DEB", "Debian packages",
cmCPackDebGenerator::CreateGenerator);
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
index 4666dc2..3092508 100644
--- a/Source/CPack/cmCPackSTGZGenerator.cxx
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -8,12 +8,16 @@
#include <string>
#include <vector>
+#include "cmArchiveWrite.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
#include "cmSystemTools.h"
#include "cm_sys_stat.h"
-cmCPackSTGZGenerator::cmCPackSTGZGenerator() = default;
+cmCPackSTGZGenerator::cmCPackSTGZGenerator()
+ : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr", ".sh")
+{
+}
cmCPackSTGZGenerator::~cmCPackSTGZGenerator() = default;
diff --git a/Source/CPack/cmCPackSTGZGenerator.h b/Source/CPack/cmCPackSTGZGenerator.h
index 9cf184b..55e4779 100644
--- a/Source/CPack/cmCPackSTGZGenerator.h
+++ b/Source/CPack/cmCPackSTGZGenerator.h
@@ -5,8 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include "cmCPackArchiveGenerator.h"
#include "cmCPackGenerator.h"
-#include "cmCPackTGZGenerator.h"
#include <iosfwd>
@@ -14,10 +14,10 @@
* \brief A generator for Self extractable TGZ files
*
*/
-class cmCPackSTGZGenerator : public cmCPackTGZGenerator
+class cmCPackSTGZGenerator : public cmCPackArchiveGenerator
{
public:
- cmCPackTypeMacro(cmCPackSTGZGenerator, cmCPackTGZGenerator);
+ cmCPackTypeMacro(cmCPackSTGZGenerator, cmCPackArchiveGenerator);
/**
* Construct generator
@@ -29,7 +29,6 @@ protected:
int PackageFiles() override;
int InitializeInternal() override;
int GenerateHeader(std::ostream* os) override;
- const char* GetOutputExtension() override { return ".sh"; }
};
#endif
diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx
deleted file mode 100644
index 6f4676e..0000000
--- a/Source/CPack/cmCPackTGZGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTGZGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTGZGenerator::cmCPackTGZGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, "paxr")
-{
-}
-
-cmCPackTGZGenerator::~cmCPackTGZGenerator() = default;
diff --git a/Source/CPack/cmCPackTGZGenerator.h b/Source/CPack/cmCPackTGZGenerator.h
deleted file mode 100644
index 7be3d9d..0000000
--- a/Source/CPack/cmCPackTGZGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTGZGenerator_h
-#define cmCPackTGZGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTGZGenerator
- * \brief A generator for TGZ files
- *
- */
-class cmCPackTGZGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTGZGenerator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTGZGenerator();
- ~cmCPackTGZGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.gz"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackTXZGenerator.cxx b/Source/CPack/cmCPackTXZGenerator.cxx
deleted file mode 100644
index ccbccde..0000000
--- a/Source/CPack/cmCPackTXZGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTXZGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTXZGenerator::cmCPackTXZGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, "paxr")
-{
-}
-
-cmCPackTXZGenerator::~cmCPackTXZGenerator() = default;
diff --git a/Source/CPack/cmCPackTXZGenerator.h b/Source/CPack/cmCPackTXZGenerator.h
deleted file mode 100644
index 4aa5973..0000000
--- a/Source/CPack/cmCPackTXZGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTXZGenerator_h
-#define cmCPackTXZGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTXZGenerator
- * \brief A generator for TXZ files
- *
- */
-class cmCPackTXZGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTXZGenerator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTXZGenerator();
- ~cmCPackTXZGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.xz"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx
deleted file mode 100644
index 85abeb1..0000000
--- a/Source/CPack/cmCPackTarBZip2Generator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTarBZip2Generator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, "paxr")
-{
-}
-
-cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator() = default;
diff --git a/Source/CPack/cmCPackTarBZip2Generator.h b/Source/CPack/cmCPackTarBZip2Generator.h
deleted file mode 100644
index 7975dda..0000000
--- a/Source/CPack/cmCPackTarBZip2Generator.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTarBZip2Generator_h
-#define cmCPackTarBZip2Generator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTarBZip2Generator
- * \brief A generator for TarBZip2 files
- */
-class cmCPackTarBZip2Generator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTarBZip2Generator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTarBZip2Generator();
- ~cmCPackTarBZip2Generator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.bz2"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx
deleted file mode 100644
index 55a6de5..0000000
--- a/Source/CPack/cmCPackTarCompressGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackTarCompressGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, "paxr")
-{
-}
-
-cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator() = default;
diff --git a/Source/CPack/cmCPackTarCompressGenerator.h b/Source/CPack/cmCPackTarCompressGenerator.h
deleted file mode 100644
index 37c7f48..0000000
--- a/Source/CPack/cmCPackTarCompressGenerator.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackTarCompressGenerator_h
-#define cmCPackTarCompressGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackTarCompressGenerator
- * \brief A generator for TarCompress files
- */
-class cmCPackTarCompressGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackTarCompressGenerator, cmCPackArchiveGenerator);
- /**
- * Construct generator
- */
- cmCPackTarCompressGenerator();
- ~cmCPackTarCompressGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".tar.Z"; }
-};
-
-#endif
diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx
deleted file mode 100644
index f06494c..0000000
--- a/Source/CPack/cmCPackZIPGenerator.cxx
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmCPackZIPGenerator.h"
-
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-
-cmCPackZIPGenerator::cmCPackZIPGenerator()
- : cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, "zip")
-{
-}
-
-cmCPackZIPGenerator::~cmCPackZIPGenerator() = default;
diff --git a/Source/CPack/cmCPackZIPGenerator.h b/Source/CPack/cmCPackZIPGenerator.h
deleted file mode 100644
index 58ec79e..0000000
--- a/Source/CPack/cmCPackZIPGenerator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
-#ifndef cmCPackZIPGenerator_h
-#define cmCPackZIPGenerator_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackGenerator.h"
-
-/** \class cmCPackZIPGenerator
- * \brief A generator for ZIP files
- */
-class cmCPackZIPGenerator : public cmCPackArchiveGenerator
-{
-public:
- cmCPackTypeMacro(cmCPackZIPGenerator, cmCPackArchiveGenerator);
-
- /**
- * Construct generator
- */
- cmCPackZIPGenerator();
- ~cmCPackZIPGenerator() override;
-
-protected:
- const char* GetOutputExtension() override { return ".zip"; }
-};
-
-#endif
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);
}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 48eebcc..8fd5234 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -576,3 +576,4 @@ endif()
add_RunCMake_test("CTestCommandExpandLists")
add_RunCMake_test(PrecompileHeaders)
+add_RunCMake_test("UnityBuild")
diff --git a/Tests/RunCMake/UnityBuild/CMakeLists.txt b/Tests/RunCMake/UnityBuild/CMakeLists.txt
new file mode 100644
index 0000000..77030d6
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.15)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
new file mode 100644
index 0000000..8e484d0
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
@@ -0,0 +1,23 @@
+include(RunCMake)
+
+run_cmake(unitybuild_c)
+run_cmake(unitybuild_cxx)
+run_cmake(unitybuild_c_and_cxx)
+run_cmake(unitybuild_batchsize)
+run_cmake(unitybuild_default_batchsize)
+run_cmake(unitybuild_skip)
+run_cmake(unitybuild_code_before_and_after_include)
+run_cmake(unitybuild_c_no_unity_build)
+run_cmake(unitybuild_order)
+
+function(run_test name)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake(${name})
+ run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
+ run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+endfunction()
+
+run_test(unitybuild_runtest)
diff --git a/Tests/RunCMake/UnityBuild/func.c b/Tests/RunCMake/UnityBuild/func.c
new file mode 100644
index 0000000..b14c907
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/func.c
@@ -0,0 +1,6 @@
+#include "func.h"
+
+int func(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/UnityBuild/func.h b/Tests/RunCMake/UnityBuild/func.h
new file mode 100644
index 0000000..563a980
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/func.h
@@ -0,0 +1,6 @@
+#ifndef func_h
+#define func_h
+
+extern int func(void);
+
+#endif
diff --git a/Tests/RunCMake/UnityBuild/main.c b/Tests/RunCMake/UnityBuild/main.c
new file mode 100644
index 0000000..19c18d4
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/main.c
@@ -0,0 +1,6 @@
+#include "func.h"
+
+int main(void)
+{
+ return func();
+}
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_batchsize-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_batchsize-check.cmake
new file mode 100644
index 0000000..32bb8e7
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_batchsize-check.cmake
@@ -0,0 +1,11 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+set(unitybuild_c1 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_1.c")
+if(NOT EXISTS "${unitybuild_c0}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.")
+ return()
+endif()
+
+if(NOT EXISTS "${unitybuild_c1}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c1} does not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_batchsize.cmake b/Tests/RunCMake/UnityBuild/unitybuild_batchsize.cmake
new file mode 100644
index 0000000..7caf251
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_batchsize.cmake
@@ -0,0 +1,16 @@
+project(unitybuild_batchsize C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt
+ PROPERTIES
+ UNITY_BUILD ON
+ UNITY_BUILD_BATCH_SIZE 4
+)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c-check.cmake
new file mode 100644
index 0000000..c980df0
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c-check.cmake
@@ -0,0 +1,5 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c.cmake
new file mode 100644
index 0000000..77a09cb
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c.cmake
@@ -0,0 +1,12 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx-check.cmake
new file mode 100644
index 0000000..32c2992
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx-check.cmake
@@ -0,0 +1,11 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.")
+ return()
+endif()
+
+set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.cxx")
+if(NOT EXISTS "${unitybuild_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_cxx} does not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx.cmake
new file mode 100644
index 0000000..073aff2
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx.cmake
@@ -0,0 +1,17 @@
+project(unitybuild_c_and_cxx C CXX)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src_c}" "int s${s}(void) { return 0; }\n")
+
+ set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src_cxx}" "int s${s}(void) { return 0; }\n")
+
+ list(APPEND srcs "${src_c}")
+ list(APPEND srcs "${src_cxx}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build-check.cmake
new file mode 100644
index 0000000..cb71ea3
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build-check.cmake
@@ -0,0 +1,5 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+if(EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} should not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build.cmake
new file mode 100644
index 0000000..1185e9f
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build.cmake
@@ -0,0 +1,10 @@
+project(unitybuild_c_no_unity_build C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include-check.cmake
new file mode 100644
index 0000000..8fcb18f
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include-check.cmake
@@ -0,0 +1,7 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+string(REGEX MATCH "#define NOMINMAX.*#include.*s1.c.*#undef NOMINMAX" matched_code ${unitybuild_c_strings})
+if(NOT matched_code)
+ set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected code before and after include")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include.cmake b/Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include.cmake
new file mode 100644
index 0000000..cc9cc28
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_code_before_and_after_include.cmake
@@ -0,0 +1,13 @@
+project(unitybuild_code_before_and_after_include C)
+
+set(src "${CMAKE_CURRENT_BINARY_DIR}/s1.c")
+file(WRITE "${src}" "int s1(void) { return 0; }\n")
+
+add_library(tgt SHARED ${src})
+
+set_target_properties(tgt
+ PROPERTIES
+ UNITY_BUILD ON
+ UNITY_BUILD_CODE_BEFORE_INCLUDE "#define NOMINMAX"
+ UNITY_BUILD_CODE_AFTER_INCLUDE "#undef NOMINMAX"
+)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx-check.cmake
new file mode 100644
index 0000000..89a037a
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx-check.cmake
@@ -0,0 +1,5 @@
+set(unitybuild_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.cxx")
+if(NOT EXISTS "${unitybuild_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_cxx} does not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx.cmake
new file mode 100644
index 0000000..be800d7
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx.cmake
@@ -0,0 +1,12 @@
+project(unitybuild_cxx CXX)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_default_batchsize-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_default_batchsize-check.cmake
new file mode 100644
index 0000000..7dfc007
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_default_batchsize-check.cmake
@@ -0,0 +1,7 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+file(STRINGS ${unitybuild_c0} unitybuild_c_strings REGEX "/s[0-9]+.c\"$" )
+list(LENGTH unitybuild_c_strings number_of_includes)
+if(NOT number_of_includes EQUAL 8)
+ set(RunCMake_TEST_FAILED "Generated unity doesn't include the expect number of files")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_default_batchsize.cmake b/Tests/RunCMake/UnityBuild/unitybuild_default_batchsize.cmake
new file mode 100644
index 0000000..60b9875
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_default_batchsize.cmake
@@ -0,0 +1,15 @@
+project(unitybuild_default_batchsize C)
+
+set(srcs "")
+foreach(s RANGE 1 10)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt
+ PROPERTIES
+ UNITY_BUILD ON
+)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
new file mode 100644
index 0000000..533a89c
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_order-check.cmake
@@ -0,0 +1,7 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+string(REGEX MATCH ".*#include.*s3.c.*#include.*s1.c.*#include.*s2.c.*" matched_code ${unitybuild_c_strings})
+if(NOT matched_code)
+ set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected oder of source files")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_order.cmake b/Tests/RunCMake/UnityBuild/unitybuild_order.cmake
new file mode 100644
index 0000000..819603d
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_order.cmake
@@ -0,0 +1,12 @@
+project(unitybuild_order C)
+
+set(srcs "")
+foreach(s 3 1 2)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake b/Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake
new file mode 100644
index 0000000..8816299
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_runtest.cmake
@@ -0,0 +1,8 @@
+project(unitybuild_runtest C)
+
+set(CMAKE_UNITY_BUILD ON) # This tests that the variable works in addition to the property
+
+add_executable(main main.c func.c)
+
+enable_testing()
+add_test(NAME main COMMAND main)
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake
new file mode 100644
index 0000000..fdd45bc
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_skip-check.cmake
@@ -0,0 +1,14 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+file(STRINGS ${unitybuild_c} unitybuild_c_strings)
+
+string(REGEX MATCH "\\/s[1-6].c" matched_files_1_6 ${unitybuild_c_strings})
+if(matched_files_1_6)
+ set(RunCMake_TEST_FAILED "Generated unity contains s1.c -> s6.c which should have been skipped")
+ return()
+endif()
+
+string(REGEX MATCH "\\/s[7-8].c" matched_files_7_8 ${unitybuild_c_strings})
+if(NOT matched_files_7_8)
+ set(RunCMake_TEST_FAILED "Generated unity should have contained s7.c, s8.c!")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_skip.cmake b/Tests/RunCMake/UnityBuild/unitybuild_skip.cmake
new file mode 100644
index 0000000..74524ad
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_skip.cmake
@@ -0,0 +1,30 @@
+project(unitybuild_skip C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON)
+
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s1.c
+ PROPERTIES GENERATED ON)
+
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s2.c
+ PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
+
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s3.c
+ PROPERTIES COMPILE_OPTIONS "val")
+
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s4.c
+ PROPERTIES COMPILE_DEFINITIONS "val")
+
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s5.c
+ PROPERTIES COMPILE_FLAGS "val")
+
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/s6.c
+ PROPERTIES INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 72154e7..dcdd177 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -34,3 +34,12 @@ endif()
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.20)
run_cmake(VsSpectreMitigation)
endif()
+
+# Visual Studio 2017 has toolset version 141
+string(REPLACE "v" "" generator_toolset "${RunCMake_GENERATOR_TOOLSET}")
+if (RunCMake_GENERATOR MATCHES "Visual Studio 1[0-4] 201[0-5]" OR
+ (RunCMake_GENERATOR_TOOLSET AND generator_toolset VERSION_LESS "141"))
+ run_cmake(UnityBuildPre2017)
+else()
+ run_cmake(UnityBuildNative)
+endif()
diff --git a/Tests/RunCMake/VS10Project/UnityBuildNative-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildNative-check.cmake
new file mode 100644
index 0000000..87f247d
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildNative-check.cmake
@@ -0,0 +1,45 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+if(NOT EXISTS "${unitybuild_c0}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.")
+ return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
+if (NOT EXISTS "${tgt_project}")
+ set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+ return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+ if (line MATCHES "<EnableUnitySupport>true</EnableUnitySupport>")
+ set(have_unity_support ON)
+ endif()
+
+ if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"false\" CustomUnityFile=\"true\"")
+ set(unity_source_line ${line})
+ endif()
+
+ if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"true\" CustomUnityFile=\"true\"")
+ list(APPEND sources_list ${line})
+ endif()
+endforeach()
+
+if (NOT have_unity_support)
+ set(RunCMake_TEST_FAILED "Generated project should include the <EnableUnitySupport> block.")
+ return()
+endif()
+
+string(REPLACE "\\" "/" unity_source_line "${unity_source_line}")
+string(FIND "${unity_source_line}" "CMakeFiles/tgt.dir/Unity/unity_0.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+ set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file.")
+ return()
+endif()
+
+list(LENGTH sources_list number_of_sources)
+if(NOT number_of_sources EQUAL 8)
+ set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/UnityBuildNative.cmake b/Tests/RunCMake/VS10Project/UnityBuildNative.cmake
new file mode 100644
index 0000000..77a09cb
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildNative.cmake
@@ -0,0 +1,12 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON)
diff --git a/Tests/RunCMake/VS10Project/UnityBuildPre2017-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildPre2017-check.cmake
new file mode 100644
index 0000000..1c6bab8
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildPre2017-check.cmake
@@ -0,0 +1,48 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0.c")
+if(NOT EXISTS "${unitybuild_c0}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.")
+ return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
+if (NOT EXISTS "${tgt_project}")
+ set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+ return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+ if (line MATCHES "<ClCompile Include=.*/>")
+ set(unity_source_line ${line})
+ endif()
+
+ if (line MATCHES "<ClCompile Include=\"[^\"]*\">")
+ string(REGEX MATCH "<ClCompile Include=\"([^\"]*)\">" source_file ${line})
+ list(APPEND sources_list ${source_file})
+ endif()
+
+ if (line MATCHES "<ExcludedFromBuild.*</ExcludedFromBuild>")
+ list(APPEND excluded_sources_list ${source_file})
+ endif()
+endforeach()
+
+string(REPLACE "\\" "/" unity_source_line ${unity_source_line})
+string(FIND "${unity_source_line}" "CMakeFiles/tgt.dir/Unity/unity_0.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+ set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file.")
+ return()
+endif()
+
+list(LENGTH sources_list number_of_sources)
+if(NOT number_of_sources EQUAL 8)
+ set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.")
+ return()
+endif()
+
+# Exclusions for Debug|Release|MinSizeRel|RelWithDebInfo
+list(LENGTH excluded_sources_list number_of_excluded_sources)
+if(NOT number_of_excluded_sources EQUAL 32)
+ set(RunCMake_TEST_FAILED "Generated project doesn't exclude the source files for all configurations.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/UnityBuildPre2017.cmake b/Tests/RunCMake/VS10Project/UnityBuildPre2017.cmake
new file mode 100644
index 0000000..77a09cb
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildPre2017.cmake
@@ -0,0 +1,12 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON)