Merge topic 'swift-module-nested-structure'

1711e86d6c Swift: Generate nested swift modules in build dir
b36175abdb Swift: Detect module triple from compiler

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !10664
This commit is contained in:
Brad King
2025-05-23 12:23:11 +00:00
committed by Kitware Robot
17 changed files with 125 additions and 15 deletions

View File

@@ -98,6 +98,7 @@ Policies Introduced by CMake 4.1
.. toctree::
:maxdepth: 1
CMP0195: Swift modules in build trees use the Swift module directory structure. </policy/CMP0195>
CMP0194: MSVC is not an assembler for language ASM. </policy/CMP0194>
CMP0193: GNUInstallDirs caches CMAKE_INSTALL_* with leading 'usr/' for install prefix '/'. </policy/CMP0193>
CMP0192: GNUInstallDirs uses absolute SYSCONFDIR, LOCALSTATEDIR, and RUNSTATEDIR in special prefixes. </policy/CMP0192>

27
Help/policy/CMP0195.rst Normal file
View File

@@ -0,0 +1,27 @@
CMP0195
-------
.. versionadded:: 4.1
Swift modules in build trees use the Swift module directory structure.
The Swift compiler emits several supplementary files that make up the
interface to a Swift library. It accepts finding these files separately
or in a single swiftmodule directory. The single file keeps things better
organized and makes it easier to install the resulting products.
CMake versions 4.1 and above prefer to generate the modules in the
directory structure when working with a new enough Swift compiler.
This policy provides compatibility for projects that have not been
updated to expect the new behavior.
The ``OLD`` behavior for this policy is to emit the interface files directly
into the current binary directory.
The ``NEW`` behavior for this policy is to gather the binary swiftmodule and
other supplemental compiler outputs in a single Swift module directory.
.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.1
.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
.. include:: include/STANDARD_ADVICE.rst
.. include:: include/DEPRECATED.rst

View File

@@ -126,6 +126,19 @@ elseif(NOT DEFINED CMAKE_Swift_COMPILER_USE_OLD_DRIVER)
unset(_CMAKE_Swift_COMPILER_CHECK_OUTPUT)
endif()
if(CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 5.2)
set(target_info_command "${CMAKE_Swift_COMPILER}" -print-target-info)
if(CMAKE_Swift_COMPILER_TARGET)
list(APPEND target_info_command -target ${CMAKE_Swift_COMPILER_TARGET})
endif()
execute_process(
COMMAND ${target_info_command}
OUTPUT_VARIABLE swift_target_info)
message(CONFIGURE_LOG "Swift target info:\n" "${swift_target_info}")
string(JSON module_triple GET "${swift_target_info}" "target" "moduleTriple")
set(CMAKE_Swift_MODULE_TRIPLE ${module_triple})
endif()
if (NOT _CMAKE_TOOLCHAIN_LOCATION)
get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Swift_COMPILER}" PATH)
endif ()

View File

@@ -16,3 +16,5 @@ set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift)
set(CMAKE_Swift_COMPILER_USE_OLD_DRIVER "@CMAKE_Swift_COMPILER_USE_OLD_DRIVER@")
set(CMAKE_Swift_IMPLICIT_INCLUDE_DIRECTORIES "@CMAKE_Swift_IMPLICIT_INCLUDE_DIRECTORIES@")
set(CMAKE_Swift_MODULE_TRIPLE "@CMAKE_Swift_MODULE_TRIPLE@")

View File

@@ -6002,8 +6002,15 @@ std::string cmGeneratorTarget::GetSwiftModuleName() const
std::string cmGeneratorTarget::GetSwiftModuleFileName() const
{
return this->GetPropertyOrDefault(
std::string moduleFilename = this->GetPropertyOrDefault(
"Swift_MODULE", this->GetSwiftModuleName() + ".swiftmodule");
if (this->GetPolicyStatusCMP0195() == cmPolicies::NEW) {
if (cmValue moduleTriple =
this->Makefile->GetDefinition("CMAKE_Swift_MODULE_TRIPLE")) {
moduleFilename += "/" + *moduleTriple + ".swiftmodule";
}
}
return moduleFilename;
}
std::string cmGeneratorTarget::GetSwiftModuleDirectory(

View File

@@ -580,7 +580,11 @@ class cmMakefile;
"install prefix '/'.", \
4, 1, 0, WARN) \
SELECT(POLICY, CMP194, "MSVC is not an assembler for language ASM.", 4, 1, \
0, WARN)
0, WARN) \
SELECT( \
POLICY, CMP0195, \
"Swift modules in build trees use the Swift module directory structure.", \
4, 1, 0, WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -627,7 +631,8 @@ class cmMakefile;
F(CMP0162) \
F(CMP0179) \
F(CMP0181) \
F(CMP0182)
F(CMP0182) \
F(CMP0195)
#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \
F(CMP0116) \

View File

@@ -0,0 +1 @@
swiftc(.exe)? .* -emit-module -emit-module-path El(/|\\)((Debug|Release)(/|\\))?El\.swiftmodule(/|\\)[-_a-z0-9]+\.swiftmodule -module-name El

View File

@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 4.0)
cmake_policy(SET CMP0195 NEW)
include(CMP0195-common.cmake)

View File

@@ -0,0 +1 @@
swiftc(.exe)? .* -emit-module -emit-module-path El(/|\\)((Debug|Release)(/|\\))?El.swiftmodule -module-name El

View File

@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 4.0)
cmake_policy(SET CMP0195 OLD)
include(CMP0195-common.cmake)

View File

@@ -0,0 +1,6 @@
enable_language(Swift)
add_library(L OBJECT L.swift)
set_target_properties(L PROPERTIES
Swift_MODULE_NAME El
Swift_MODULE_DIRECTORY El)

View File

@@ -3,31 +3,32 @@ if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
return()
endif()
set(ESCAPED_BINARY_DIR [==[[^
]*/Tests/RunCMake/Swift/CompileCommands-build]==])
set(E_SOURCE_PATH [==[(\\")?[^
]*(/Tests/RunCMake/Swift/E.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\E.swift)(\\")?]==])
set(L_SOURCE_PATH [==[(\\")?[^
]*(/Tests/RunCMake/Swift/L.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\L.swift)(\\")?]==])
# The compile command for both files should contain all Swift source files in
# the module
set(expected_compile_commands
[==[^\[
{
"directory": "[^
]*/Tests/RunCMake/Swift/CompileCommands-build",
"directory": "${BINARY_DIR}",
"command": "[^
]*swiftc[^
]* (\\")?[^
]*(/Tests/RunCMake/Swift/E.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\E.swift)(\\")? (\\")?[^
]*(/Tests/RunCMake/Swift/L.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\L.swift)(\\")?",
]* ${E_SOURCE_PATH} ${L_SOURCE_PATH}",
"file": "[^
]*/Tests/RunCMake/Swift/E.swift",
"output": "[^
]*/CMakeFiles/CompileCommandLib.dir/(Debug/)?E.swift.(o|obj)"
},
{
"directory": "[^
]*/Tests/RunCMake/Swift/CompileCommands-build",
"directory": "${BINARY_DIR}",
"command": "[^
]*swiftc[^
]* (\\")?[^
]*(/Tests/RunCMake/Swift/E.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\E.swift)(\\")? (\\")?[^
]*(/Tests/RunCMake/Swift/L.swift|\\\\Tests\\\\RunCMake\\\\Swift\\\\L.swift)(\\")?",
]* ${E_SOURCE_PATH} ${L_SOURCE_PATH}",
"file": "[^
]*/Tests/RunCMake/Swift/L.swift",
"output": "[^
@@ -35,6 +36,10 @@ set(expected_compile_commands
}]==]
)
string(REPLACE [=[${BINARY_DIR}]=] "${ESCAPED_BINARY_DIR}" expected_compile_commands "${expected_compile_commands}")
string(REPLACE [=[${E_SOURCE_PATH}]=] "${E_SOURCE_PATH}" expected_compile_commands "${expected_compile_commands}")
string(REPLACE [=[${L_SOURCE_PATH}]=] "${L_SOURCE_PATH}" expected_compile_commands "${expected_compile_commands}")
file(READ "${RunCMake_TEST_BINARY_DIR}/compile_commands.json" compile_commands)
if(NOT compile_commands MATCHES "${expected_compile_commands}")
string(REPLACE "\n" "\n " expected_compile_commands_formatted "${expected_compile_commands}")

View File

@@ -1,6 +1,10 @@
if(POLICY CMP0157)
cmake_policy(SET CMP0157 NEW)
endif()
if(POLICY CMP0195)
cmake_policy(SET CMP0195 NEW)
endif()
set(CMAKE_Swift_COMPILATION_MODE "singlefile")
enable_language(Swift)

View File

@@ -1,4 +1,7 @@
cmake_policy(SET CMP0157 NEW)
if(POLICY CMP0195)
cmake_policy(SET CMP0195 NEW)
endif()
enable_language(Swift)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/hello.swift "")

View File

@@ -30,6 +30,21 @@ block()
endif()
endblock()
if(RunCMake_GENERATOR MATCHES "Ninja.*")
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0195-NEW-build)
run_cmake(CMP0195-NEW)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(CMP0195-NEW-build ${CMAKE_COMMAND} --build . -- -n -v)
endblock()
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0195-OLD-build)
run_cmake(CMP0195-OLD)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(CMP0195-OLD-build ${CMAKE_COMMAND} --build . -- -n -v)
endblock()
endif()
block()
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SwiftSimple-build)
run_cmake(SwiftSimple)

View File

@@ -46,6 +46,7 @@
\* CMP0179
\* CMP0181
\* CMP0182
\* CMP0195
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@@ -5,6 +5,10 @@ endif()
if(POLICY CMP0157)
cmake_policy(SET CMP0157 NEW)
endif()
if(POLICY CMP0195)
cmake_policy(SET CMP0195 NEW)
set(Swift_NESTED_MODULE TRUE)
endif()
# NOTE: Force the Release mode configuration as there are some issues with the
# debug information handling on macOS on certain Xcode builds.
@@ -52,11 +56,18 @@ target_link_libraries(N PUBLIC
# FIXME(#25989): The Xcode generator doesn't respect CMAKE_Swift_MODULE_DIRECTORY.
if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
if(Swift_NESTED_MODULE)
# Swift module is a directory, grab the binary swiftmodule file
set(ModulePath "${CMAKE_Swift_MODULE_DIRECTORY}/M.swiftmodule/${CMAKE_Swift_MODULE_TRIPLE}.swiftmodule")
else()
# Swift modules are files
set(ModulePath "${CMAKE_Swift_MODULE_DIRECTORY}/M.swiftmodule")
endif()
add_custom_command(TARGET M
POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E compare_files
"${CMAKE_Swift_MODULE_DIRECTORY}/M.swiftmodule"
"${CMAKE_Swift_MODULE_DIRECTORY}/M.swiftmodule"
"${ModulePath}"
"${ModulePath}"
COMMENT "check that .swiftmodule files are generated in CMAKE_Swift_MODULE_DIRECTORY"
VERBATIM)
endif()