Merge topic 'swift-cmp0215-update'

e4a37fbf15 Tests/RunCMake/Swift: Add CMP0195 behavior checks
b7a78568c3 CMP0215: Update NEW behavior to require CMP0157/CMP0195 to be NEW

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !12407
This commit is contained in:
Brad King authored and Kitware Robot committed 2026-08-14 06:30:36 -04:00
commit ca0ed0f66f
18 files changed
+118 -59

No files matched your search

+9 -7
View File
@@ -24,13 +24,15 @@ The :prop_tgt:`Swift_SEPARATE_MODULE_EMISSION` target property and
corresponding :variable:`CMAKE_Swift_SEPARATE_MODULE_EMISSION` variable
may be set to enable or disable the behavior on a per-target basis.
.. note::
Separate module emission takes effect only when policy :policy:`CMP0157`
is set to ``NEW`` prior to the first :command:`project` or
:command:`enable_language` command that enables the Swift language.
The dedicated ``.swiftmodule`` edge is available only in the split
Swift build model.
The ``NEW`` behavior requires that policies :policy:`CMP0157` and
:policy:`CMP0195` are also set to ``NEW``. :policy:`CMP0157` selects the
split Swift build model that provides the dedicated ``.swiftmodule`` edge,
and must be set prior to the first :command:`project` or
:command:`enable_language` command that enables the Swift language.
:policy:`CMP0195` places the module in the Swift module directory structure
that the dedicated edge writes. If either policy is not ``NEW`` while
``CMP0215`` is ``NEW``, CMake issues a fatal error when the Swift language
is enabled.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.4
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+9 -1
View File
@@ -322,7 +322,9 @@ Swift
:prop_tgt:`Swift_SEPARATE_MODULE_EMISSION` target property, initialized by
the :variable:`CMAKE_Swift_SEPARATE_MODULE_EMISSION` variable, to control
whether importable Swift targets emit ``.swiftmodule`` from a dedicated
build edge. Policy :policy:`CMP0215` enables this by default.
build edge. Policy :policy:`CMP0215` enables this by default. The
behavior requires policies :policy:`CMP0157` and :policy:`CMP0195` to be
set to ``NEW``.
* The default :prop_tgt:`Swift_MODULE_NAME` now replaces hyphens with
underscores, since hyphens are not valid in Swift module identifiers.
@@ -450,3 +452,9 @@ Changes made since CMake 4.4.0 include the following.
* This version made no changes to documented features or interfaces.
Some implementation updates were made to support ecosystem changes
and/or fix regressions.
.. 4.4.3
* Swift policy :policy:`CMP0215`'s ``NEW`` behavior has been updated
to require policies :policy:`CMP0157` and :policy:`CMP0195` to also
be set to ``NEW``.
+41
View File
@@ -109,6 +109,47 @@ else()
endif()
unset(__SWIFT_COMP_MODE_CMP0157)
# Separate Swift module emission (see policy CMP0215) is available only in the
# split build model selected by policy CMP0157, and it writes the module into
# the Swift module directory structure selected by policy CMP0195. When
# CMP0215 is NEW, require both to also be NEW. This is a Ninja-only feature,
# so only enforce the requirement for Ninja generators.
if(CMAKE_GENERATOR MATCHES "Ninja")
cmake_policy(GET CMP0215 __SWIFT_SEPARATE_MODULE_CMP0215)
if(__SWIFT_SEPARATE_MODULE_CMP0215 STREQUAL "NEW")
set(__SWIFT_SEPARATE_MODULE_UNMET "")
cmake_policy(GET CMP0157 __SWIFT_SEPARATE_MODULE_CMP0157)
if(NOT __SWIFT_SEPARATE_MODULE_CMP0157 STREQUAL "NEW")
list(APPEND __SWIFT_SEPARATE_MODULE_UNMET CMP0157)
endif()
cmake_policy(GET CMP0195 __SWIFT_SEPARATE_MODULE_CMP0195)
if(NOT __SWIFT_SEPARATE_MODULE_CMP0195 STREQUAL "NEW")
list(APPEND __SWIFT_SEPARATE_MODULE_UNMET CMP0195)
endif()
if(__SWIFT_SEPARATE_MODULE_UNMET)
list(LENGTH __SWIFT_SEPARATE_MODULE_UNMET __SWIFT_SEPARATE_MODULE_UNMET_COUNT)
list(JOIN __SWIFT_SEPARATE_MODULE_UNMET " and " __SWIFT_SEPARATE_MODULE_UNMET_STR)
if(__SWIFT_SEPARATE_MODULE_UNMET_COUNT GREATER 1)
set(__SWIFT_SEPARATE_MODULE_VERB "are")
else()
set(__SWIFT_SEPARATE_MODULE_VERB "is")
endif()
message(FATAL_ERROR
"Policy CMP0215 is set to 'NEW', which requires policies CMP0157 and "
"CMP0195 to be set to 'NEW', but ${__SWIFT_SEPARATE_MODULE_UNMET_STR} "
"${__SWIFT_SEPARATE_MODULE_VERB} not. Note that CMP0157 must be set "
"before the Swift language is enabled.")
endif()
unset(__SWIFT_SEPARATE_MODULE_CMP0157)
unset(__SWIFT_SEPARATE_MODULE_CMP0195)
unset(__SWIFT_SEPARATE_MODULE_UNMET)
unset(__SWIFT_SEPARATE_MODULE_UNMET_COUNT)
unset(__SWIFT_SEPARATE_MODULE_UNMET_STR)
unset(__SWIFT_SEPARATE_MODULE_VERB)
endif()
unset(__SWIFT_SEPARATE_MODULE_CMP0215)
endif()
cmake_initialize_per_config_variable(CMAKE_Swift_FLAGS "Swift Compiler Flags")
if(NOT CMAKE_Swift_NUM_THREADS MATCHES "^[0-9]+$")
+6 -11
View File
@@ -1293,7 +1293,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
this->GeneratorTarget->GetObjectSources(objectSources, config);
std::vector<cmSourceFile const*> swiftSources;
for (cmSourceFile const* sf : objectSources) {
if (this->GetLocalGenerator()->IsSplitSwiftBuild() &&
sf->GetLanguage() == "Swift") {
@@ -1303,6 +1302,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
firstForConfig);
}
}
WriteSwiftObjectBuildStatement(swiftSources, config, fileConfig,
firstForConfig);
}
@@ -2244,9 +2244,6 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
this->GetGlobalGenerator()->GetLanguageOutputExtension(language)));
objBuild.RspFile = cmStrCat(targetObjectFilename, ".swift.rsp");
// Importable targets keep -emit-module on compile so swiftc still emits
// .swiftdoc. When splitting module emission, both the .swiftmodule output
// and -emit-module flags move entirely to the separate emit-module edge.
if (targetIsImportable) {
this->Configs[config].SwiftModuleOutput = moduleFilepath;
}
@@ -2288,8 +2285,8 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
std::string const moduleOutputPath =
this->LocalGenerator->ConvertToOutputFormat(moduleFilepath,
cmOutputConverter::SHELL);
if (targetIsImportable && !emitModuleSeparately &&
commonFlags.find("-emit-module-path") == std::string::npos) {
if (targetIsImportable && !emitModuleSeparately) {
std::string const emitModuleFlag = "-emit-module";
std::string const modulePathFlag = "-emit-module-path";
this->LocalGenerator->AppendFlags(
@@ -2338,11 +2335,9 @@ void cmNinjaTargetGenerator::WriteSwiftObjectBuildStatement(
// Skip if the flags already contain one (e.g. a directory-style path
// set by the target's compile options).
modBuild.Variables["FLAGS"] = commonFlags;
if (commonFlags.find("-emit-module-path") == std::string::npos) {
this->LocalGenerator->AppendFlags(
modBuild.Variables["FLAGS"],
cmStrCat("-emit-module-path ", moduleOutputPath));
}
this->LocalGenerator->AppendFlags(
modBuild.Variables["FLAGS"],
cmStrCat("-emit-module-path ", moduleOutputPath));
modBuild.RspFile = cmStrCat(moduleFilepath, ".rsp");
@@ -1,4 +1,5 @@
cmake_policy(SET CMP0157 NEW)
cmake_policy(SET CMP0195 NEW)
cmake_policy(SET CMP0215 NEW)
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
@@ -1,3 +1,9 @@
# Older Swift compilers may not set CMAKE_Swift_MODULE_TRIPLE
# Check that we built something before verifying the output
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/no-swift-module-triple")
return()
endif()
string(
REGEX MATCHALL
"swiftc(\\.exe)?\"? [^\n]* -emit-module-path [^\n]*L\\.swiftmodule[^ \n]*"
@@ -10,6 +10,13 @@ endif()
enable_language(Swift)
# Older Swift compilers may not set CMAKE_Swift_MODULE_TRIPLE
# Don't build anything if we can't do the nested module structure
if(NOT CMAKE_Swift_MODULE_TRIPLE)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/no-swift-module-triple" "")
return()
endif()
add_library(L STATIC L.swift)
add_library(LClient STATIC LClient.swift)
target_link_libraries(LClient PRIVATE L)
@@ -1,11 +0,0 @@
# When the target's flags already contain -emit-module-path, the emit-module
# edge should not append a second one that clobbers it.
# Match command lines that have two -emit-module-path flags on the same line.
string(
REGEX MATCHALL
"-emit-module-path [^\n]*-emit-module-path"
duplicate_flags "${actual_stdout}")
if(duplicate_flags)
string(APPEND RunCMake_TEST_FAILED
"Found command with duplicate -emit-module-path flags.\n")
endif()
@@ -1,22 +0,0 @@
cmake_minimum_required(VERSION 4.0)
cmake_policy(SET CMP0157 NEW)
cmake_policy(SET CMP0195 NEW)
cmake_policy(SET CMP0215 NEW)
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
message(SEND_ERROR "this test must use a Ninja generator, found ${CMAKE_GENERATOR}")
endif()
enable_language(Swift)
add_library(L STATIC L.swift)
add_library(LClient STATIC LClient.swift)
target_link_libraries(LClient PRIVATE L)
# Simulate a target whose flags already contain -emit-module-path with a
# directory-style path (as seen with swift-syntax's CMake config). Use the
# real module triple so the path matches GetSwiftModulePath() and the build
# would succeed outside of dry-run.
target_compile_options(L PRIVATE
-emit-module-path ${CMAKE_CURRENT_BINARY_DIR}/L.swiftmodule/${CMAKE_Swift_MODULE_TRIPLE}.swiftmodule)
@@ -1,4 +1,5 @@
cmake_policy(SET CMP0157 NEW)
cmake_policy(SET CMP0195 NEW)
cmake_policy(SET CMP0215 NEW)
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
@@ -1,4 +1,5 @@
cmake_policy(SET CMP0157 NEW)
cmake_policy(SET CMP0195 NEW)
cmake_policy(SET CMP0215 NEW)
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
@@ -1,4 +1,5 @@
cmake_policy(SET CMP0157 NEW)
cmake_policy(SET CMP0195 NEW)
cmake_policy(SET CMP0215 NEW)
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
@@ -0,0 +1,4 @@
CMake Error at [^
]*CMakeSwiftInformation\.cmake:[0-9]+ \(message\):
Policy CMP0215 is set to 'NEW', which requires policies CMP0157 and CMP0195
to be set to 'NEW', but CMP0157 and CMP0195 are not\.
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 4.0)
# CMP0157 must be set before the Swift language is enabled.
cmake_policy(SET CMP0157 OLD)
cmake_policy(SET CMP0195 OLD)
cmake_policy(SET CMP0215 NEW)
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
message(SEND_ERROR "this test must use a Ninja generator, found ${CMAKE_GENERATOR}")
endif()
# CMP0215=NEW requires both CMP0157=NEW and CMP0195=NEW; neither is set here,
# so enabling the Swift language must fail and name both policies.
enable_language(Swift)
@@ -1,3 +1,9 @@
# Older Swift compilers may not set CMAKE_Swift_MODULE_TRIPLE
# Check that we built something before verifying the output
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/no-swift-module-triple")
return()
endif()
if(NOT actual_stdout MATCHES
"swiftc(\\.exe)?\"? [^\n]* -c @CMakeFiles(/|\\\\)L\\.dir(/|\\\\)(Debug(/|\\\\))?L\\.o(bj)?\\.swift\\.rsp")
string(APPEND RunCMake_TEST_FAILED
@@ -5,7 +11,7 @@ if(NOT actual_stdout MATCHES
endif()
if(NOT actual_stdout MATCHES
"swiftc(\\.exe)?\"? [^\n]* -emit-module @.*L\\.swiftmodule\\.rsp")
"swiftc(\\.exe)?\"? [^\n]* -emit-module @.*L\\.swiftmodule(/|\\\\)[-_a-zA-Z0-9]+\\.swiftmodule\\.rsp")
string(APPEND RunCMake_TEST_FAILED
"No Swift emit-module response-file command found for target L.\n")
endif()
@@ -1,4 +1,5 @@
cmake_policy(SET CMP0157 NEW)
cmake_policy(SET CMP0195 NEW)
cmake_policy(SET CMP0215 NEW)
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
@@ -9,6 +10,13 @@ set(CMAKE_NINJA_FORCE_RESPONSE_FILE TRUE)
enable_language(Swift)
# Older Swift compilers may not set CMAKE_Swift_MODULE_TRIPLE
# Don't build anything if we can't do the nested module structure
if(NOT CMAKE_Swift_MODULE_TRIPLE)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/no-swift-module-triple" "")
return()
endif()
add_library(L STATIC L.swift)
add_library(LClient STATIC LClient.swift)
target_link_libraries(LClient PRIVATE L)
+2 -6
View File
@@ -184,15 +184,11 @@ if(RunCMake_GENERATOR MATCHES "Ninja")
endblock()
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/EmitModuleSeparatelyExistingModulePath-build)
run_cmake(EmitModuleSeparatelyExistingModulePath)
set(RunCMake_TEST_NO_CLEAN 1)
# -v: verbose to capture executed commands -n: dry-run to avoid actually compiling
run_cmake_command(EmitModuleSeparatelyExistingModulePath-build ${CMAKE_COMMAND} --build . -- -vn)
run_cmake(EmitModuleSeparatelyOrdering)
endblock()
block()
run_cmake(EmitModuleSeparatelyOrdering)
run_cmake(EmitModuleSeparatelyRequiresPolicies)
endblock()
block()