summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYR Chen <stevapple@icloud.com>2023-03-25 16:51:50 +0800
committerBrad King <brad.king@kitware.com>2023-03-28 10:02:05 -0400
commit006e1995ebd279052290bf3e25eb814ba09a0dcc (patch)
treebba0f36344dd0d171c42d36235d8317704633f8e
parentfae6e8c2cdb5ce6049439f4defd1367b507d1e4b (diff)
downloadcmake-006e1995ebd279052290bf3e25eb814ba09a0dcc.tar.gz
Swift: Restore compatibility with old C++ driver
The `-wmo` flag added by commit 6063428de7 (Swift: Update default build flags, 2022-10-03, v3.26.0-rc1~585^2~1) behaves differently with the old driver. Detect when the old driver is being used, and avoid adding that flag. Fixes: #24641
-rw-r--r--Modules/CMakeDetermineSwiftCompiler.cmake59
-rw-r--r--Modules/CMakeSwiftCompiler.cmake.in2
-rw-r--r--Modules/CMakeSwiftInformation.cmake14
3 files changed, 72 insertions, 3 deletions
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
index aaad5601da..f0a63a8cff 100644
--- a/Modules/CMakeDetermineSwiftCompiler.cmake
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -63,6 +63,65 @@ if(NOT CMAKE_Swift_COMPILER_ID_RUN)
CMAKE_DETERMINE_COMPILER_ID(Swift "" CompilerId/main.swift)
endif()
+# Check if we are using the old compiler driver.
+if(CMAKE_GENERATOR STREQUAL "Xcode")
+ # For Xcode, we can decide driver kind simply by Swift version.
+ if(CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 5.5)
+ set(CMAKE_Swift_COMPILER_USE_OLD_DRIVER FALSE)
+ else()
+ set(CMAKE_Swift_COMPILER_USE_OLD_DRIVER TRUE)
+ endif()
+elseif(NOT DEFINED CMAKE_Swift_COMPILER_USE_OLD_DRIVER)
+ # Dry-run a WMO build to identify the compiler driver.
+
+ # Create a clean directory in which to run the test.
+ set(CMAKE_Swift_COMPILER_DRIVER_TEST_DIR ${CMAKE_PLATFORM_INFO_DIR}/SwiftCompilerDriver)
+ file(REMOVE_RECURSE "${CMAKE_Swift_COMPILER_DRIVER_TEST_DIR}")
+ file(MAKE_DIRECTORY "${CMAKE_Swift_COMPILER_DRIVER_TEST_DIR}")
+
+ # Create a Swift file and an arbitrary linker resource.
+ file(WRITE ${CMAKE_Swift_COMPILER_DRIVER_TEST_DIR}/main.swift "print(\"Hello\")\n")
+ file(WRITE ${CMAKE_Swift_COMPILER_DRIVER_TEST_DIR}/lib.in "\n")
+
+ # Honor user-specified compiler flags.
+ if(DEFINED CMAKE_Swift_FLAGS)
+ separate_arguments(_CMAKE_Swift_COMPILER_FLAGS_LIST NATIVE_COMMAND "${CMAKE_Swift_FLAGS}")
+ else()
+ separate_arguments(_CMAKE_Swift_COMPILER_FLAGS_LIST NATIVE_COMMAND "${CMAKE_Swift_FLAGS_INIT}")
+ endif()
+ set(_CMAKE_Swift_COMPILER_CHECK_COMMAND "${CMAKE_Swift_COMPILER}" ${_CMAKE_Swift_COMPILER_FLAGS_LIST} -wmo main.swift lib.in "-###")
+ unset(_CMAKE_Swift_COMPILER_FLAGS_LIST)
+
+ # Execute in dry-run mode so no compilation will be actually performed.
+ execute_process(COMMAND ${_CMAKE_Swift_COMPILER_CHECK_COMMAND}
+ WORKING_DIRECTORY "${CMAKE_Swift_COMPILER_DRIVER_TEST_DIR}"
+ OUTPUT_VARIABLE _CMAKE_Swift_COMPILER_CHECK_OUTPUT)
+
+ # Check the first frontend execution. It is on the first line of output.
+ # The old driver treats all inputs as Swift sources while the new driver
+ # can identify "lib.in" as a linker resource.
+ if("${_CMAKE_Swift_COMPILER_CHECK_OUTPUT}" MATCHES "^[^\n]* lib\\.in")
+ set(CMAKE_Swift_COMPILER_USE_OLD_DRIVER TRUE)
+ else()
+ set(CMAKE_Swift_COMPILER_USE_OLD_DRIVER FALSE)
+ endif()
+
+ # Record the check results in the configure log.
+ list(TRANSFORM _CMAKE_Swift_COMPILER_CHECK_COMMAND PREPEND "\"")
+ list(TRANSFORM _CMAKE_Swift_COMPILER_CHECK_COMMAND APPEND "\"")
+ list(JOIN _CMAKE_Swift_COMPILER_CHECK_COMMAND " " _CMAKE_Swift_COMPILER_CHECK_COMMAND)
+ string(REPLACE "\n" "\n " _CMAKE_Swift_COMPILER_CHECK_OUTPUT " ${_CMAKE_Swift_COMPILER_CHECK_OUTPUT}")
+ message(CONFIGURE_LOG
+ "Detected CMAKE_Swift_COMPILER_USE_OLD_DRIVER=\"${CMAKE_Swift_COMPILER_USE_OLD_DRIVER}\" from:\n"
+ " ${_CMAKE_Swift_COMPILER_CHECK_COMMAND}\n"
+ "with output:\n"
+ "${_CMAKE_Swift_COMPILER_CHECK_OUTPUT}"
+ )
+
+ unset(_CMAKE_Swift_COMPILER_CHECK_COMMAND)
+ unset(_CMAKE_Swift_COMPILER_CHECK_OUTPUT)
+endif()
+
if (NOT _CMAKE_TOOLCHAIN_LOCATION)
get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Swift_COMPILER}" PATH)
endif ()
diff --git a/Modules/CMakeSwiftCompiler.cmake.in b/Modules/CMakeSwiftCompiler.cmake.in
index 47ada38c2c..b3851908aa 100644
--- a/Modules/CMakeSwiftCompiler.cmake.in
+++ b/Modules/CMakeSwiftCompiler.cmake.in
@@ -13,4 +13,6 @@ set(CMAKE_Swift_COMPILER_ENV_VAR "SWIFTC")
set(CMAKE_Swift_COMPILER_ID_RUN 1)
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@")
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index a75dfceea1..f524955861 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -78,9 +78,17 @@ if(CMAKE_GENERATOR STREQUAL "Xcode")
set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
else()
set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g -incremental")
- set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O -wmo")
- set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g -wmo")
- set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize -wmo")
+ 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")
+ endif()
endif()
if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")