summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Wilde <etceterawilde@gmail.com>2023-11-06 00:36:28 (GMT)
committerBrad King <brad.king@kitware.com>2023-11-17 13:43:21 (GMT)
commitc1d787e4734ca107e8ae084b3832e441651a6266 (patch)
tree9622a28a3c0e14caa452ac4ddb6733fa83564088
parentc39384f54019adce87d676a7ed6d8e772ce5b7f8 (diff)
downloadCMake-c1d787e4734ca107e8ae084b3832e441651a6266.zip
CMake-c1d787e4734ca107e8ae084b3832e441651a6266.tar.gz
CMake-c1d787e4734ca107e8ae084b3832e441651a6266.tar.bz2
Swift: Add abstraction for compilation mode
Add a `CMAKE_Swift_COMPILATION_MODE` variable and corresponding `Swift_COMPILATION_MODE` target property to control the compilation mode. Select among `wholemodule`, `singlefile`, and `incremental`. Add policy CMP0157 to remove the default `-wmo` flags in favor of the abstract setting. Issue: #25366
-rw-r--r--Auxiliary/vim/syntax/cmake.vim1
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/policy/CMP0157.rst48
-rw-r--r--Help/prop_tgt/Swift_COMPILATION_MODE-VALUES.txt19
-rw-r--r--Help/prop_tgt/Swift_COMPILATION_MODE.rst33
-rw-r--r--Help/variable/CMAKE_Swift_COMPILATION_MODE.rst32
-rw-r--r--Modules/CMakeSwiftInformation.cmake46
-rw-r--r--Source/cmCoreTryCompile.cxx8
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx36
-rw-r--r--Source/cmLocalGenerator.cxx61
-rw-r--r--Source/cmLocalGenerator.h13
-rw-r--r--Source/cmPolicies.h8
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Tests/RunCMake/Swift/CMP0157-NEW-stderr.txt3
-rw-r--r--Tests/RunCMake/Swift/CMP0157-NEW.cmake4
-rw-r--r--Tests/RunCMake/Swift/CMP0157-OLD.cmake4
-rw-r--r--Tests/RunCMake/Swift/CMP0157-WARN.cmake3
-rw-r--r--Tests/RunCMake/Swift/CMP0157-common.cmake19
-rw-r--r--Tests/RunCMake/Swift/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt1
-rw-r--r--Tests/SwiftOnly/CMakeLists.txt20
23 files changed, 353 insertions, 22 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index a13dfc9..1a21387 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -374,6 +374,7 @@ syn keyword cmakeProperty contained
\ Swift_LANGUAGE_VERSION
\ Swift_MODULE_DIRECTORY
\ Swift_MODULE_NAME
+ \ Swift_COMPILATION_MODE
\ TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
\ TARGET_MESSAGES
\ TARGET_SUPPORTS_SHARED_LIBS
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 5b1939e..ddde877 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.29
.. toctree::
:maxdepth: 1
+ CMP0157: Swift compilation mode is selected by an abstraction. </policy/CMP0157>
CMP0156: De-duplicate libraries on link lines based on linker capabilities. </policy/CMP0156>
Policies Introduced by CMake 3.28
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 55054f5..fbf0fbc 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -392,6 +392,7 @@ Properties on Targets
/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG
/prop_tgt/STATIC_LIBRARY_OPTIONS
/prop_tgt/SUFFIX
+ /prop_tgt/Swift_COMPILATION_MODE
/prop_tgt/Swift_DEPENDENCIES_FILE
/prop_tgt/Swift_LANGUAGE_VERSION
/prop_tgt/Swift_MODULE_DIRECTORY
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 4ce3b2f..6445bcb 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -115,6 +115,7 @@ Variables that Provide Information
/variable/CMAKE_SOURCE_DIR
/variable/CMAKE_STATIC_LIBRARY_PREFIX
/variable/CMAKE_STATIC_LIBRARY_SUFFIX
+ /variable/CMAKE_Swift_COMPILATION_MODE
/variable/CMAKE_Swift_MODULE_DIRECTORY
/variable/CMAKE_Swift_NUM_THREADS
/variable/CMAKE_TOOLCHAIN_FILE
diff --git a/Help/policy/CMP0157.rst b/Help/policy/CMP0157.rst
new file mode 100644
index 0000000..a8f8210
--- /dev/null
+++ b/Help/policy/CMP0157.rst
@@ -0,0 +1,48 @@
+CMP0157
+-------
+
+.. versionadded:: 3.29
+
+Swift compilation mode is selected by an abstraction.
+
+The Swift compiler can compile modules in different modes. The desired build
+mode depends whether the developer is iterating and wants to incrementally make
+changes, or if they are building a release for distribution and want more
+optimizations applied to the resulting binary.
+
+CMake versions 3.26 through 3.28 build Swift binaries with whole-module
+optimizations enabled when configured in a non-debug build type.
+For CMake versions earlier than 3.26, the developer needs to specify
+the necessary flag manually for the :ref:`Ninja Generators`, and cannot
+not specify whole-module optimizations to the :generator:`Xcode` generator.
+
+CMake versions 3.29 and above prefer to set the compilation mode using
+the :prop_tgt:`Swift_COMPILATION_MODE` target property, which can be
+initialized by the :variable:`CMAKE_Swift_COMPILATION_MODE` variable.
+
+This policy provides compatibility for projects that have not been updated.
+The policy setting takes effect as of the first :command:`project` or
+:command:`enable_language` command that enables the ``Swift`` language.
+
+.. note::
+
+ Once the policy has taken effect at the top of a project, that choice
+ must be used throughout the tree. In projects that have nested projects
+ in subdirectories, be sure to convert everything together.
+
+The ``OLD`` behavior for this policy builds all Swift targets in
+``wholemodule`` mode for non-debug configurations. :ref:`Ninja Generators`
+prepend the ``-wmo`` flag to the default set of Swift flags.
+The :generator:`Xcode` generator sets the ``SWIFT_COMPILATION_MODE``
+attribute to ``wholemodule`` in the generated Xcode project file.
+
+The ``NEW`` behavior for this policy is to apply the compilation mode specified
+in the :prop_tgt:`Swift_COMPILATION_MODE` target property, initialized as each
+target is created by the :variable:`CMAKE_Swift_COMPILATION_MODE` variable.
+
+This policy was introduced in CMake version 3.29. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn when this policy
+is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/Swift_COMPILATION_MODE-VALUES.txt b/Help/prop_tgt/Swift_COMPILATION_MODE-VALUES.txt
new file mode 100644
index 0000000..b94380a
--- /dev/null
+++ b/Help/prop_tgt/Swift_COMPILATION_MODE-VALUES.txt
@@ -0,0 +1,19 @@
+``incremental``
+ Compiles each Swift source in the module separately, resulting in better
+ parallelism in the build. The compiler emits additional information into
+ the build directory improving rebuild performance when small changes are made
+ to the source between rebuilds. This is the best option to use while
+ iterating on changes in a project.
+
+``wholemodule``
+ Whole-module optimizations are slowest to compile, but results in the most
+ optimized library. The entire context is loaded into once instance of the
+ compiler, so there is no parallelism across source files in the module.
+
+``singlefile``
+ Compiles each source in a Swift modules separately, resulting in better
+ parallelism. Unlike the ``incremental`` build mode, no additional information
+ is emitted by the compiler during the build, so rebuilding after making small
+ changes to the source file will not run faster. This option should be used
+ sparingly, preferring ``incremental`` builds, unless working around a compiler
+ bug.
diff --git a/Help/prop_tgt/Swift_COMPILATION_MODE.rst b/Help/prop_tgt/Swift_COMPILATION_MODE.rst
new file mode 100644
index 0000000..e26474a
--- /dev/null
+++ b/Help/prop_tgt/Swift_COMPILATION_MODE.rst
@@ -0,0 +1,33 @@
+Swift_COMPILATION_MODE
+----------------------
+
+.. versionadded:: 3.29
+
+Specify how Swift compiles a target.
+
+The allowed values are:
+
+.. include:: Swift_COMPILATION_MODE-VALUES.txt
+
+Use :manual:`generator expressions <cmake-generator-expressions(7)>` to support
+per-configuration specification. For example, the code:
+
+.. code-block:: cmake
+
+ add_library(foo foo.swift)
+ set_property(TARGET foo PROPERTY
+ Swift_COMPILATION_MODE "$<IF:$<CONFIG:Release>,wholemodule,incremental>")
+
+sets the Swift compilation mode to wholemodule mode in the release configuration
+and sets the property to incremental mode in other configurations.
+
+The property is initialized from the value of the
+:variable:`CMAKE_Swift_COMPILATION_MODE` variable, if it is set. If the property
+is not set or is empty, then CMake uses the default value ``incremental`` to
+specify the swift compilation mode.
+
+.. note::
+
+ This property only has effect when policy :policy:`CMP0157` is set to ``NEW``
+ prior to the first :command:`project` or :command:`enable_language` command
+ that enables the Swift language.
diff --git a/Help/variable/CMAKE_Swift_COMPILATION_MODE.rst b/Help/variable/CMAKE_Swift_COMPILATION_MODE.rst
new file mode 100644
index 0000000..5e55d8c
--- /dev/null
+++ b/Help/variable/CMAKE_Swift_COMPILATION_MODE.rst
@@ -0,0 +1,32 @@
+CMAKE_Swift_COMPILATION_MODE
+----------------------------
+
+.. versionadded:: 3.29
+
+Specify how Swift compiles a target. This variable is used to initialize the
+:prop_tgt:`Swift_COMPILATION_MODE` property on targets as they are created.
+
+The allowed values are:
+
+.. include:: ../prop_tgt/Swift_COMPILATION_MODE-VALUES.txt
+
+Use :manual:`generator expressions <cmake-generator-expressions(7)>` to support
+per-configuration specification. For example, the code:
+
+.. code-block:: cmake
+
+ set(CMAKE_Swift_COMPILATION_MODE
+ "$<IF:$<CONFIG:Release>,wholemodule,incremental>")
+
+sets the default Swift compilation mode to wholemodule mode when building a
+release configuration and to incremental mode in other configurations.
+
+If this variable is not set then the :prop_tgt:`Swift_COMPILATION_MODE` target
+property will not be set automatically. If that property is unset then CMake
+uses the default value ``incremental`` to build the Swift source files.
+
+.. note::
+
+ This property only has effect when policy :policy:`CMP0157` is set to ``NEW``
+ prior to the first :command:`project` or :command:`enable_language` command
+ that enables the Swift language.
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 1c6f0df..9f4ed34 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -68,30 +68,42 @@ set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -libc MD)
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -libc MTd)
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -libc MDd)
+set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g")
+set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
+set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
+
if(CMAKE_GENERATOR STREQUAL "Xcode")
+ string(APPEND CMAKE_Swift_FLAGS_DEBUG_INIT " ${CMAKE_Swift_FLAGS_DEBUG_LINKER_FLAGS}")
+ string(APPEND CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT " ${CMAKE_Swift_FLAGS_RELWITHDEBINFO_LINKER_FLAGS}")
+endif()
+
+# Warns if unset and uses old policy.
+# Old policy flag-smashes the wmo and incremental flags onto the compiler flags.
+# New policy respects the Swift_COMPILATION_MODE target property to add
+# incremental and wholemodule optimization flags as appropriate.
+cmake_policy(GET CMP0157 __SWIFT_COMP_MODE_CMP0157)
+if(__SWIFT_COMP_MODE_CMP0157 STREQUAL "NEW")
+ set(CMAKE_Swift_COMPILATION_MODE_DEFAULT "incremental")
+else()
# Xcode has a separate Xcode project option (SWIFT_COMPILATION_MODE) used to set
# whether compiling with whole-module optimizations or incrementally. Setting
# these options here will have no effect when compiling with the built-in driver,
# and will explode violently, leaving build products in the source directory, when
- # using the old swift driver.
- set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g ${CMAKE_Swift_FLAGS_DEBUG_LINKER_FLAGS}")
- set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
- set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g ${CMAKE_Swift_FLAGS_RELWITHDEBINFO_LINKER_FLAGS}")
- set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
-else()
- set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g -incremental")
- set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
- set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
- set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
-
- # Enable Whole Module Optimization by default unless the old
- # C++ driver is being used, which behaves differently under WMO.
- if(NOT CMAKE_Swift_COMPILER_USE_OLD_DRIVER)
- string(APPEND CMAKE_Swift_FLAGS_RELEASE_INIT " -wmo")
- string(APPEND CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT " -wmo")
- string(APPEND CMAKE_Swift_FLAGS_MINSIZEREL_INIT " -wmo")
+ # using the old swift driver. Don't append `-incremental` or `-wmo` to the
+ # flags in the Xcode generator.
+ if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ # Enable Whole Module Optimization by default unless the old
+ # C++ driver is being used, which behaves differently under WMO.
+ if(NOT CMAKE_Swift_COMPILER_USE_OLD_DRIVER)
+ string(APPEND CMAKE_Swift_FLAGS_RELEASE_INIT " -wmo")
+ string(APPEND CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT " -wmo")
+ string(APPEND CMAKE_Swift_FLAGS_MINSIZEREL_INIT " -wmo")
+ endif()
+ string(APPEND CMAKE_Swift_FLAGS_DEBUG_INIT " -incremental")
endif()
endif()
+unset(__SWIFT_COMP_MODE_CMP0157)
if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
if(NOT DEFINED CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG)
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 7f7c747..fa30b06 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -904,6 +904,14 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
? "NEW"
: "OLD");
+ /* Set the appropriate policy information for Swift compilation mode */
+ fprintf(
+ fout, "cmake_policy(SET CMP0157 %s)\n",
+ this->Makefile->GetDefinition("CMAKE_Swift_COMPILATION_MODE_DEFAULT")
+ .IsEmpty()
+ ? "OLD"
+ : "NEW");
+
// Workaround for -Wl,-headerpad_max_install_names issue until we can avoid
// adding that flag in the platform and compiler language files
fprintf(fout,
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 2e6ed37..1429ee3 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2479,6 +2479,25 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("SWIFT_ACTIVE_COMPILATION_CONDITIONS",
swiftDefs.CreateList());
}
+
+ if (cm::optional<cmSwiftCompileMode> swiftCompileMode =
+ this->CurrentLocalGenerator->GetSwiftCompileMode(gtgt, configName)) {
+ switch (*swiftCompileMode) {
+ case cmSwiftCompileMode::Wholemodule:
+ buildSettings->AddAttribute("SWIFT_COMPILATION_MODE",
+ this->CreateString("wholemodule"));
+ break;
+ case cmSwiftCompileMode::Incremental:
+ case cmSwiftCompileMode::Singlefile:
+ break;
+ case cmSwiftCompileMode::Unknown:
+ this->CurrentLocalGenerator->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat("Unknown Swift_COMPILATION_MODE on target '",
+ gtgt->GetName(), "'"));
+ break;
+ }
+ }
}
std::string extraLinkOptionsVar;
@@ -4610,6 +4629,10 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
buildSettings->AddAttribute("CODE_SIGNING_ALLOWED",
this->CreateString("NO"));
}
+
+ // This code supports the OLD behavior of CMP0157. We should be able to
+ // remove computing the debug configuration set once the old behavior is
+ // removed.
auto debugConfigs = this->GetCMakeInstance()->GetDebugConfigs();
std::set<std::string> debugConfigSet(debugConfigs.begin(),
debugConfigs.end());
@@ -4619,9 +4642,16 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings);
- if (debugConfigSet.count(cmSystemTools::UpperCase(config.first)) == 0) {
- buildSettingsForCfg->AddAttribute("SWIFT_COMPILATION_MODE",
- this->CreateString("wholemodule"));
+ // Supports the OLD behavior of CMP0157. CMP0157 OLD behavior globally set
+ // wholemodule compilation for all non-debug configurations, for all
+ // targets.
+ if (this->CurrentMakefile
+ ->GetDefinition("CMAKE_Swift_COMPILATION_MODE_DEFAULT")
+ .IsEmpty()) {
+ if (debugConfigSet.count(cmSystemTools::UpperCase(config.first)) == 0) {
+ buildSettingsForCfg->AddAttribute("SWIFT_COMPILATION_MODE",
+ this->CreateString("wholemodule"));
+ }
}
// Put this last so it can override existing settings
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index be18c29..eaf38d4 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1651,6 +1651,39 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
if (lang == "Fortran") {
this->AppendFlags(compileFlags,
this->GetTargetFortranFlags(target, config));
+ } else if (lang == "Swift") {
+ // Only set the compile mode if CMP0157 is set
+ if (cm::optional<cmSwiftCompileMode> swiftCompileMode =
+ this->GetSwiftCompileMode(target, config)) {
+ std::string swiftCompileModeFlag;
+ switch (*swiftCompileMode) {
+ case cmSwiftCompileMode::Incremental: {
+ swiftCompileModeFlag = "-incremental";
+ if (cmValue flag =
+ mf->GetDefinition("CMAKE_Swift_COMPILE_OPTIONS_INCREMENTAL")) {
+ swiftCompileModeFlag = *flag;
+ }
+ break;
+ }
+ case cmSwiftCompileMode::Wholemodule: {
+ swiftCompileModeFlag = "-wmo";
+ if (cmValue flag =
+ mf->GetDefinition("CMAKE_Swift_COMPILE_OPTIONS_WMO")) {
+ swiftCompileModeFlag = *flag;
+ }
+ break;
+ }
+ case cmSwiftCompileMode::Singlefile:
+ break;
+ case cmSwiftCompileMode::Unknown: {
+ this->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat("Unknown Swift_COMPILATION_MODE on target '",
+ target->GetName(), "'"));
+ }
+ }
+ this->AppendFlags(compileFlags, swiftCompileModeFlag);
+ }
}
this->AddCMP0018Flags(compileFlags, target, lang, config);
@@ -2955,6 +2988,34 @@ cm::optional<std::string> cmLocalGenerator::GetMSVCDebugFormatName(
return msvcDebugInformationFormat;
}
+cm::optional<cmSwiftCompileMode> cmLocalGenerator::GetSwiftCompileMode(
+ cmGeneratorTarget const* target, std::string const& config)
+{
+ cmMakefile const* mf = this->GetMakefile();
+ cmValue const swiftCompileModeDefault =
+ mf->GetDefinition("CMAKE_Swift_COMPILATION_MODE_DEFAULT");
+ if (!cmNonempty(swiftCompileModeDefault)) {
+ return {};
+ }
+ cmValue swiftCompileMode = target->GetProperty("Swift_COMPILATION_MODE");
+ if (!swiftCompileMode) {
+ swiftCompileMode = swiftCompileModeDefault;
+ }
+
+ std::string const expandedCompileMode =
+ cmGeneratorExpression::Evaluate(*swiftCompileMode, this, config, target);
+ if (expandedCompileMode == "wholemodule") {
+ return cmSwiftCompileMode::Wholemodule;
+ }
+ if (expandedCompileMode == "singlefile") {
+ return cmSwiftCompileMode::Singlefile;
+ }
+ if (expandedCompileMode == "incremental") {
+ return cmSwiftCompileMode::Incremental;
+ }
+ return cmSwiftCompileMode::Unknown;
+}
+
namespace {
inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index a61def9..af5b35e 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -67,6 +67,15 @@ enum class cmBuildStep
Link
};
+/** What compilation mode the swift files are in */
+enum class cmSwiftCompileMode
+{
+ Wholemodule,
+ Incremental,
+ Singlefile,
+ Unknown,
+};
+
/** Target and source file which have a specific output. */
struct cmSourcesWithOutput
{
@@ -549,6 +558,10 @@ public:
const std::string& prop,
const std::string& config);
+ // Return Swift_COMPILATION_MODE value if CMP0157 is NEW.
+ cm::optional<cmSwiftCompileMode> GetSwiftCompileMode(
+ cmGeneratorTarget const* target, std::string const& config);
+
protected:
// The default implementation converts to a Windows shortpath to
// help older toolchains handle spaces and such. A generator may
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 8aace68..7964f32 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -477,7 +477,10 @@ class cmMakefile;
SELECT( \
POLICY, CMP0156, \
"De-duplicate libraries on link lines based on linker capabilities.", 3, \
- 29, 0, cmPolicies::WARN)
+ 29, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0157, \
+ "Swift compilation mode selected by an abstraction.", 3, 29, 0, \
+ cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -518,7 +521,8 @@ class cmMakefile;
F(CMP0142) \
F(CMP0154) \
F(CMP0155) \
- F(CMP0156)
+ F(CMP0156) \
+ F(CMP0157)
#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \
F(CMP0116) \
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d93f658..346e3dc 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -438,6 +438,7 @@ TargetProperty const StaticTargetProperties[] = {
// ---- Swift
{ "Swift_LANGUAGE_VERSION"_s, IC::CanCompileSources },
{ "Swift_MODULE_DIRECTORY"_s, IC::CanCompileSources },
+ { "Swift_COMPILATION_MODE"_s, IC::CanCompileSources },
// ---- moc
{ "AUTOMOC"_s, IC::CanCompileSources },
{ "AUTOMOC_COMPILER_PREDEFINES"_s, IC::CanCompileSources },
diff --git a/Tests/RunCMake/Swift/CMP0157-NEW-stderr.txt b/Tests/RunCMake/Swift/CMP0157-NEW-stderr.txt
new file mode 100644
index 0000000..82adcda
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMP0157-NEW-stderr.txt
@@ -0,0 +1,3 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Unknown Swift_COMPILATION_MODE on target 'greetings_who_knows'
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/Swift/CMP0157-NEW.cmake b/Tests/RunCMake/Swift/CMP0157-NEW.cmake
new file mode 100644
index 0000000..96c2ff4
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMP0157-NEW.cmake
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.28)
+
+cmake_policy(SET CMP0157 NEW)
+include(CMP0157-common.cmake)
diff --git a/Tests/RunCMake/Swift/CMP0157-OLD.cmake b/Tests/RunCMake/Swift/CMP0157-OLD.cmake
new file mode 100644
index 0000000..6b0ec94
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMP0157-OLD.cmake
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.28)
+
+cmake_policy(SET CMP0157 OLD)
+include(CMP0157-common.cmake)
diff --git a/Tests/RunCMake/Swift/CMP0157-WARN.cmake b/Tests/RunCMake/Swift/CMP0157-WARN.cmake
new file mode 100644
index 0000000..7d8c01d
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMP0157-WARN.cmake
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.28)
+
+include(CMP0157-common.cmake)
diff --git a/Tests/RunCMake/Swift/CMP0157-common.cmake b/Tests/RunCMake/Swift/CMP0157-common.cmake
new file mode 100644
index 0000000..53f14f6
--- /dev/null
+++ b/Tests/RunCMake/Swift/CMP0157-common.cmake
@@ -0,0 +1,19 @@
+enable_language(Swift)
+
+add_executable(greetings_default hello.swift)
+
+add_executable(greetings_wmo hello.swift)
+set_target_properties(greetings_wmo PROPERTIES
+ Swift_COMPILATION_MODE "wholemodule")
+
+add_executable(greetings_incremental hello.swift)
+set_target_properties(greetings_incremental PROPERTIES
+ Swift_COMPILATION_MODE "incremental")
+
+add_executable(greetings_singlefile hello.swift)
+set_target_properties(greetings_singlefile PROPERTIES
+ Swift_COMPILATION_MODE "singlefile")
+
+add_executable(greetings_who_knows hello.swift)
+set_target_properties(greetings_who_knows PROPERTIES
+ Swift_COMPILATION_MODE "not-a-real-mode")
diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake
index 2d9f90d..68d10ea 100644
--- a/Tests/RunCMake/Swift/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake
@@ -3,6 +3,10 @@ include(RunCMake)
if(RunCMake_GENERATOR STREQUAL Xcode)
if(XCODE_VERSION VERSION_LESS 6.1)
run_cmake(XcodeTooOld)
+ elseif(CMake_TEST_Swift)
+ run_cmake(CMP0157-NEW)
+ run_cmake(CMP0157-OLD)
+ run_cmake(CMP0157-WARN)
endif()
elseif(RunCMake_GENERATOR STREQUAL Ninja)
if(CMake_TEST_Swift)
@@ -45,11 +49,19 @@ elseif(RunCMake_GENERATOR STREQUAL Ninja)
run_cmake_command(IncrementalSwift-second ${CMAKE_COMMAND} --build ${IncrementalSwift_TEST_BINARY_DIR} -- -d explain)
endblock()
+ run_cmake(CMP0157-NEW)
+ run_cmake(CMP0157-OLD)
+ run_cmake(CMP0157-WARN)
+
endif()
elseif(RunCMake_GENERATOR STREQUAL "Ninja Multi-Config")
if(CMake_TEST_Swift)
set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release")
run_cmake(SwiftSimple)
+
+ run_cmake(CMP0157-NEW)
+ run_cmake(CMP0157-OLD)
+ run_cmake(CMP0157-WARN)
unset(RunCMake_TEST_OPTIONS)
endif()
else()
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 389a63e..11d59b7 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -40,6 +40,7 @@
\* CMP0154
\* CMP0155
\* CMP0156
+ \* CMP0157
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index 13cf2b1..7de1e04 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.3)
if(POLICY CMP0126)
cmake_policy(SET CMP0126 NEW)
endif()
+if(POLICY CMP0157)
+ cmake_policy(SET CMP0157 NEW)
+endif()
# NOTE: Force the Release mode configuration as there are some issues with the
# debug information handling on macOS on certain Xcode builds.
@@ -54,3 +57,20 @@ target_link_libraries(SwiftOnly PRIVATE SwiftIface)
if(CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 5.2)
add_subdirectory("SwiftPlugin")
endif()
+
+function(test_cmp0157_default mode)
+
+ cmake_policy(GET CMP0157 cmp0157_wmo)
+ if(cmp0157_wmo STREQUAL "NEW")
+ set(CMAKE_Swift_COMPILATION_MODE "${mode}")
+ add_executable(hi_${mode} main.swift)
+ get_target_property(${mode}_swift_comp_mode hi_${mode} "Swift_COMPILATION_MODE")
+ if(NOT ${mode}_swift_comp_mode STREQUAL ${mode})
+ message(SEND_ERROR "expected ${mode} -- found ${${mode}_swift_comp_mode}")
+ endif()
+ endif()
+endfunction()
+
+test_cmp0157_default("wholemodule")
+test_cmp0157_default("incremental")
+test_cmp0157_default("singlefile")