Skip to content

Commit 264fbd9

Browse files
authored
Merge pull request #581 from rintaro/toolchain
Configure CMake build to install content into toolchain
2 parents b442078 + 91ffb07 commit 264fbd9

File tree

6 files changed

+202
-30
lines changed

6 files changed

+202
-30
lines changed

CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ endif()
1515
project(SwiftTesting
1616
LANGUAGES CXX Swift)
1717

18+
include(GNUInstallDirs)
19+
1820
list(APPEND CMAKE_MODULE_PATH
1921
${PROJECT_SOURCE_DIR}/cmake/modules
2022
${PROJECT_SOURCE_DIR}/cmake/modules/shared)
@@ -28,4 +30,12 @@ set(CMAKE_CXX_STANDARD 20)
2830
set(CMAKE_Swift_LANGUAGE_VERSION 6)
2931
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
3032

33+
if(NOT SWIFT_SYSTEM_NAME)
34+
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
35+
set(SWIFT_SYSTEM_NAME macosx)
36+
else()
37+
set(SWIFT_SYSTEM_NAME "$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>")
38+
endif()
39+
endif()
40+
3141
add_subdirectory(Sources)

Sources/CMakeLists.txt

Lines changed: 90 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,100 @@
66
# See http://swift.org/LICENSE.txt for license information
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9-
# Macros must be built for the build machine, not the host.
10-
include(ExternalProject)
11-
if(NOT SwiftTesting_MACRO_MAKE_PROGRAM)
12-
set(SwiftTesting_MACRO_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM})
13-
endif()
9+
set(SwiftTesting_MACRO "<auto>" CACHE STRING
10+
"Path to SwiftTesting macro plugin, or '<auto>' for automatically building it")
11+
12+
if(SwiftTesting_MACRO STREQUAL "<auto>")
13+
# Macros must be built for the build machine, not the host.
14+
include(ExternalProject)
15+
if(NOT SwiftTesting_MACRO_MAKE_PROGRAM)
16+
set(SwiftTesting_MACRO_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM})
17+
endif()
18+
if(NOT SwiftTesting_MACRO_Swift_COMPILER)
19+
set(SwiftTesting_MACRO_Swift_COMPILER ${CMAKE_Swift_COMPILER})
20+
endif()
21+
if(NOT SwiftTesting_MACRO_Swift_FLAGS)
22+
set(SwiftTesting_MACRO_Swift_FLAGS ${CMAKE_Swift_FLAGS})
23+
set(SwiftTesting_MACRO_SWIFT_FLAGS_RELEASE ${CMAKE_Swift_FLAGS_RELEASE})
24+
set(SwiftTesting_MACRO_SWIFT_FLAGS_RELWITHDEBINFO ${CMAKE_Swift_FLAGS_RELWITHDEBINFO})
25+
endif()
26+
if(NOT SwiftTesting_MACRO_AR)
27+
set(SwiftTesting_MACRO_AR ${CMAKE_AR})
28+
endif()
29+
if(NOT SwiftTesting_MACRO_RANLIB)
30+
set(SwiftTesting_MACRO_RANLIB ${CMAKE_RANLIB})
31+
endif()
32+
if(NOT SwiftTesting_MACRO_BUILD_TYPE)
33+
set(SwiftTesting_MACRO_BUILD_TYPE ${CMAKE_BUILD_TYPE})
34+
endif()
35+
36+
find_package(SwiftSyntax CONFIG GLOBAL)
37+
if(SwiftSyntax_FOUND)
38+
set(SwiftTesting_BuildMacrosAsExecutables NO)
39+
else()
40+
set(SwiftTesting_BuildMacrosAsExecutables YES)
41+
endif()
1442

15-
find_package(SwiftSyntax CONFIG GLOBAL)
16-
if(SwiftSyntax_FOUND)
17-
set(SwiftTesting_BuildMacrosAsExecutables NO)
43+
# Build and install the plugin into the current build directry.
44+
set(SwiftTesting_MACRO_INSTALL_PREFIX "${CMAKE_BINARY_DIR}")
45+
46+
ExternalProject_Add(TestingMacros
47+
PREFIX "tm"
48+
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/TestingMacros"
49+
BUILD_ALWAYS ON
50+
CMAKE_ARGS
51+
-DCMAKE_MAKE_PROGRAM=${SwiftTesting_MACRO_MAKE_PROGRAM}
52+
-DCMAKE_Swift_COMPILER=${SwiftTesting_MACRO_Swift_COMPILER}
53+
-DCMAKE_Swift_FLAGS=${SwiftTesting_MACRO_Swift_FLAGS}
54+
-DCMAKE_Swift_FLAGS_RELEASE=${SwiftTesting_MACRO_Swift_FLAGS_RELEASE}
55+
-DCMAKE_Swift_FLAGS_RELWITHDEBINFO=${SwiftTesting_MACRO_Swift_FLAGS_RELWITHDEBINFO}
56+
-DCMAKE_AR=${SwiftTesting_MACRO_AR}
57+
-DCMAKE_RANLIB=${SwiftTesting_MACRO_RANLIB}
58+
-DCMAKE_BUILD_TYPE=${CSwiftTesting_MACRO_BUILD_TYPE}
59+
-DSwiftTesting_BuildMacrosAsExecutables=${SwiftTesting_BuildMacrosAsExecutables}
60+
-DSwiftSyntax_DIR=${SwiftSyntax_DIR}
61+
-DCMAKE_INSTALL_PREFIX=${SwiftTesting_MACRO_INSTALL_PREFIX})
62+
63+
# Hardcode the known file names based on system name as a workaround since
64+
# TestingMacros uses `ExternalProject` and we cannot directly query the
65+
# properties of its targets here.
66+
if(NOT SwiftTesting_BuildMacrosAsExecutables)
67+
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
68+
set(SwiftTesting_MACRO_PATH "${SwiftTesting_MACRO_INSTALL_PREFIX}/lib/swift/host/plugins/testing/libTestingMacros.dylib")
69+
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
70+
set(SwiftTesting_MACRO_PATH "${SwiftTesting_MACRO_INSTALL_PREFIX}/lib/swift/host/plugins/libTestingMacros.so")
71+
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
72+
set(SwiftTesting_MACRO_PATH "${SwiftTesting_MACRO_INSTALL_PREFIX}/bin/TestingMacros.dll")
73+
else()
74+
message(FATAL_ERROR "Unable to determine the library name for TestingMacros based on system name: ${CMAKE_HOST_SYSTEM_NAME}")
75+
endif()
76+
else()
77+
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
78+
set(SwiftTesting_MACRO_PATH "${SwiftTesting_MACRO_INSTALL_PREFIX}/bin/TestingMacros.exe")
79+
else()
80+
set(SwiftTesting_MACRO_PATH "${SwiftTesting_MACRO_INSTALL_PREFIX}/bin/TestingMacros")
81+
endif()
82+
endif()
83+
elseif(SwiftTesting_MACRO)
84+
# Use the passed-in plugin path.
85+
set(SwiftTesting_MACRO_PATH "${SwiftTesting_MACRO}")
86+
add_custom_target(TestingMacros DEPENDS "${SwiftTesting_MACRO_PATH}")
1887
else()
19-
set(SwiftTesting_BuildMacrosAsExecutables YES)
88+
# If it's explicitly "NO", do not compile the library with macros.
89+
add_custom_target(TestingMacros)
2090
endif()
2191

22-
ExternalProject_Add(TestingMacros
23-
PREFIX "tm"
24-
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/TestingMacros"
25-
CMAKE_ARGS
26-
-DCMAKE_MAKE_PROGRAM=${SwiftTesting_MACRO_MAKE_PROGRAM}
27-
-DSwiftTesting_BuildMacrosAsExecutables=${SwiftTesting_BuildMacrosAsExecutables}
28-
-DSwiftSyntax_DIR=${SwiftSyntax_DIR}
29-
INSTALL_COMMAND "")
30-
ExternalProject_Get_Property(TestingMacros BINARY_DIR)
92+
if(NOT SwiftTesting_MACRO_PATH)
93+
message(STATUS "TestingMacros: (none)")
94+
elseif(SwiftTesting_MACRO_PATH)
95+
if(SwiftTesting_MACRO_PATH MATCHES [[\.(dylib|so|dll)$]])
96+
message(STATUS "TestingMacros: ${SwiftTesting_MACRO_PATH} (shared library)")
97+
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-load-plugin-library ${SwiftTesting_MACRO_PATH}>")
98+
else()
99+
message(STATUS "TestingMacros: ${SwiftTesting_MACRO_PATH} (executable)")
100+
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-load-plugin-exectuable ${SwiftTesting_MACRO_PATH}#TestingMacros>")
101+
endif()
102+
endif()
31103

32104
include(AvailabilityDefinitions)
33105
include(CompilerSettings)

Sources/Testing/CMakeLists.txt

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,8 @@ target_link_libraries(Testing PRIVATE
9797
add_dependencies(Testing
9898
TestingMacros)
9999
target_compile_options(Testing PRIVATE
100-
-enable-library-evolution)
100+
-enable-library-evolution
101+
-emit-module-interface -emit-module-interface-path $<TARGET_PROPERTY:Testing,Swift_MODULE_DIRECTORY>/Testing.swiftinterface)
101102

102-
if(SwiftTesting_BuildMacrosAsExecutables)
103-
if(CMAKE_HOST_WIN32)
104-
set(_TestingMacros_ExecutableSuffix ".exe")
105-
endif()
106-
107-
target_compile_options(Testing PUBLIC
108-
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-load-plugin-executable ${BINARY_DIR}/TestingMacros${_TestingMacros_ExecutableSuffix}#TestingMacros>")
109-
else()
110-
target_compile_options(Testing PUBLIC
111-
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-plugin-path ${BINARY_DIR}>")
112-
endif()
103+
include(SwiftModuleInstallation)
104+
_swift_testing_install_target(Testing)

Sources/TestingMacros/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ if(SwiftTesting_BuildMacrosAsExecutables)
5858
target_compile_definitions(TestingMacros PRIVATE SWT_NO_LIBRARY_MACRO_PLUGINS)
5959
else()
6060
add_library(TestingMacros SHARED)
61+
62+
target_link_options(TestingMacros PRIVATE "-no-toolchain-stdlib-rpath")
63+
# Not setting RPATH means it requires all the dependencies are already loaded
64+
# in the process, because 'plugin' directory wouldn't contain any dependencies.
65+
set_property(TARGET TestingMacros PROPERTY INSTALL_RPATH)
66+
set_property(TARGET TestingMacros PROPERTY BUILD_WITH_INSTALL_RPATH YES)
67+
68+
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
69+
set(plugin_destination_dir "lib/swift/host/plugins/testing")
70+
else()
71+
set(plugin_destination_dir "lib/swift/host/plugins")
72+
endif()
73+
74+
install(TARGETS TestingMacros
75+
LIBRARY DESTINATION "${plugin_destination_dir}"
76+
RUNTIME DESTINATION bin)
6177
endif()
6278

6379
target_sources(TestingMacros PRIVATE

Sources/_TestingInternals/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
# See http://swift.org/LICENSE.txt for license information
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9+
set(CMAKE_CXX_SCAN_FOR_MODULES 0)
10+
911
include(LibraryVersion)
1012
add_library(_TestingInternals STATIC
1113
Discovery.cpp
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# This source file is part of the Swift.org open source project
2+
#
3+
# Copyright (c) 2024 Apple Inc. and the Swift project authors
4+
# Licensed under Apache License v2.0 with Runtime Library Exception
5+
#
6+
# See http://swift.org/LICENSE.txt for license information
7+
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
# Returns the os name in a variable
10+
#
11+
# Usage:
12+
# get_swift_host_os(result_var_name)
13+
#
14+
#
15+
# Sets ${result_var_name} with the converted OS name derived from
16+
# CMAKE_SYSTEM_NAME.
17+
function(get_swift_host_os result_var_name)
18+
set(${result_var_name} ${SWIFT_SYSTEM_NAME} PARENT_SCOPE)
19+
endfunction()
20+
21+
function(_swift_testing_install_target module)
22+
get_swift_host_os(swift_os)
23+
get_target_property(type ${module} TYPE)
24+
25+
if(type STREQUAL STATIC_LIBRARY)
26+
set(swift swift_static)
27+
else()
28+
set(swift swift)
29+
endif()
30+
31+
target_compile_options(Testing PRIVATE "-no-toolchain-stdlib-rpath")
32+
33+
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
34+
set(lib_destination_dir "lib/${swift}/${swift_os}/testing")
35+
set_property(TARGET ${module} PROPERTY
36+
INSTALL_RPATH "@loader_path/..")
37+
else()
38+
set(lib_destination_dir "lib/${swift}/${swift_os}")
39+
set_property(TARGET ${module} PROPERTY
40+
INSTALL_RPATH "$ORIGIN")
41+
endif()
42+
43+
install(TARGETS ${module}
44+
ARCHIVE DESTINATION "${lib_destination_dir}"
45+
LIBRARY DESTINATION "${lib_destination_dir}"
46+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
47+
if(type STREQUAL EXECUTABLE)
48+
return()
49+
endif()
50+
51+
get_target_property(module_name ${module} Swift_MODULE_NAME)
52+
if(NOT module_name)
53+
set(module_name ${module})
54+
endif()
55+
56+
if(NOT SwiftTesting_MODULE_TRIPLE)
57+
set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info)
58+
if(CMAKE_Swift_COMPILER_TARGET)
59+
list(APPEND module_triple_command -target ${CMAKE_Swift_COMPILER_TARGET})
60+
endif()
61+
execute_process(COMMAND ${module_triple_command} OUTPUT_VARIABLE target_info_json)
62+
string(JSON module_triple GET "${target_info_json}" "target" "moduleTriple")
63+
set(SwiftTesting_MODULE_TRIPLE "${module_triple}" CACHE STRING "swift module triple used for installed swiftmodule and swiftinterface files")
64+
mark_as_advanced(SwiftTesting_MODULE_TRIPLE)
65+
endif()
66+
67+
set(module_dir "${lib_destination_dir}/${module_name}.swiftmodule")
68+
install(FILES $<TARGET_PROPERTY:${module},Swift_MODULE_DIRECTORY>/${module_name}.swiftdoc
69+
DESTINATION "${module_dir}"
70+
RENAME ${SwiftTesting_MODULE_TRIPLE}.swiftdoc)
71+
install(FILES $<TARGET_PROPERTY:${module},Swift_MODULE_DIRECTORY>/${module_name}.swiftmodule
72+
DESTINATION "${module_dir}"
73+
RENAME ${SwiftTesting_MODULE_TRIPLE}.swiftmodule)
74+
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
75+
# Only Darwin has stable ABI.
76+
install(FILES $<TARGET_PROPERTY:${module},Swift_MODULE_DIRECTORY>/${module_name}.swiftinterface
77+
DESTINATION "${module_dir}"
78+
RENAME ${SwiftTesting_MODULE_TRIPLE}.swiftinterface)
79+
endif()
80+
endfunction()

0 commit comments

Comments
 (0)