Skip to content

Commit 9c9010e

Browse files
committed
[CMake] Support Macros in Linux
For compiling codes required for macro support, we now need swiftc compiler in the build machine. Unlike Darwin OSes, where swiftCore runtime is guaranteed to be present in /usr/lib, Linux doesn't have ABI stability and the stdlib of the build machine is not at the specific location. So the built compiler cannot relies on the shared object in the toolchain.
1 parent 5dd2cf7 commit 9c9010e

File tree

24 files changed

+304
-77
lines changed

24 files changed

+304
-77
lines changed

Diff for: CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ include(SwiftConfigureSDK)
794794
include(SwiftComponents)
795795
include(SwiftList)
796796
include(AddPureSwift)
797+
include(SwiftStripBuilderRpath)
797798

798799
# Configure swift include, install, build components.
799800
swift_configure_components()

Diff for: SwiftCompilerSources/CMakeLists.txt

+7-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ else()
235235
#
236236
# step 1: generate a dummy source file, which just includes all headers
237237
# defined in include/swift/module.modulemap
238-
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp"
238+
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp.tmp"
239239
"
240240
#include \"Basic/BridgedSwiftObject.h\"
241241
#include \"Basic/BasicBridging.h\"
@@ -251,6 +251,12 @@ else()
251251
252252
#include \"Parse/RegexParserBridging.h\"
253253
")
254+
add_custom_command(
255+
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp"
256+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
257+
"${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp.tmp"
258+
"${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp"
259+
)
254260

255261
# step 2: build a library containing that source file. This library depends on all the included header files.
256262
# The swift modules can now depend on that target.

Diff for: cmake/modules/AddPureSwift.cmake

+22
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,27 @@ function(_add_host_swift_compile_options name)
6565
_add_host_variant_swift_sanitizer_flags(${name})
6666
endfunction()
6767

68+
function(_set_pure_swift_link_flags name relpath_to_lib_dir)
69+
if(SWIFT_HOST_VARIANT_SDK STREQUAL "LINUX")
70+
# Don't add builder's stdlib RPATH automatically, because we want to *de-prioritize* it.
71+
target_compile_options(${name} PRIVATE
72+
$<$<COMPILE_LANGUAGE:Swift>:-no-toolchain-stdlib-rpath>
73+
)
74+
75+
get_filename_component(swift_bin_dir ${CMAKE_Swift_COMPILER} DIRECTORY)
76+
get_filename_component(swift_dir ${swift_bin_dir} DIRECTORY)
77+
set(host_lib_dir "${swift_dir}/lib/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
78+
79+
set_property(TARGET ${name}
80+
APPEND PROPERTY INSTALL_RPATH
81+
# At runtime, use swiftCore in the current toolchain.
82+
"$ORIGIN/${relpath_to_lib_dir}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}"
83+
# But before building the stdlib with the tool, use the builder libs. This should be removed in install time.
84+
"${host_lib_dir}")
85+
86+
endif()
87+
endfunction()
88+
6889
# Add a new "pure" Swift host library.
6990
#
7091
# "Pure" Swift host libraries can only contain Swift code, and will be built
@@ -266,6 +287,7 @@ function(add_pure_swift_host_tool name)
266287
# Create the library.
267288
add_executable(${name} ${APSHT_SOURCES})
268289
_add_host_swift_compile_options(${name})
290+
_set_pure_swift_link_flags(${name} "../lib")
269291

270292
if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS)
271293
set_property(TARGET ${name}

Diff for: cmake/modules/AddSwift.cmake

+15-7
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,14 @@ function(_add_swift_runtime_link_flags target relpath_to_lib_dir bootstrapping)
548548
target_link_libraries(${target} PRIVATE "swiftCore")
549549

550550
target_link_directories(${target} PRIVATE ${host_lib_dir})
551+
552+
# At runtime, use swiftCore in the current toolchain.
553+
# FIXME: This assumes the ABI hasn't changed since the builder.
554+
set(swift_runtime_rpath "$ORIGIN/${relpath_to_lib_dir}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
555+
551556
if(ASRLF_BOOTSTRAPPING_MODE STREQUAL "HOSTTOOLS")
552-
set(swift_runtime_rpath "${host_lib_dir}")
553-
else()
554-
set(swift_runtime_rpath "$ORIGIN/${relpath_to_lib_dir}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
557+
# But before building the stdlib with the tool, use the builder libs. This should be removed in install time.
558+
list(APPEND swift_runtime_rpath "${host_lib_dir}")
555559
endif()
556560

557561
elseif(ASRLF_BOOTSTRAPPING_MODE STREQUAL "BOOTSTRAPPING")
@@ -576,9 +580,6 @@ function(_add_swift_runtime_link_flags target relpath_to_lib_dir bootstrapping)
576580
endif()
577581

578582
if(SWIFT_SWIFT_PARSER)
579-
# Make sure we can find the early SwiftSyntax libraries.
580-
target_link_directories(${target} PRIVATE "${SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR}/lib/swift/host")
581-
582583
# For the "end step" of bootstrapping configurations, we need to be
583584
# able to fall back to the SDK directory for libswiftCore et al.
584585
if (BOOTSTRAPPING_MODE MATCHES "BOOTSTRAPPING.*")
@@ -967,7 +968,14 @@ function(add_swift_host_tool executable)
967968
swift_install_in_component(TARGETS ${executable}
968969
RUNTIME
969970
DESTINATION bin
970-
COMPONENT ${ASHT_SWIFT_COMPONENT})
971+
COMPONENT ${ASHT_SWIFT_COMPONENT}
972+
)
973+
974+
swift_install_strip_builder_rpath(
975+
TARGETS ${executable}
976+
DESTINATION bin
977+
COMPONENT ${ASHT_SWIFT_COMPONENT}
978+
)
971979

972980
swift_is_installing_component(${ASHT_SWIFT_COMPONENT} is_installing)
973981
endif()

Diff for: cmake/modules/AddSwiftUnittests.cmake

+25-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,32 @@ add_custom_target(SwiftUnitTests)
55

66
set_target_properties(SwiftUnitTests PROPERTIES FOLDER "Tests")
77

8+
# Add a new Swift unit test executable.
9+
#
10+
# Usage:
11+
# add_swift_unittest(name
12+
# [IS_TARGET_TEST]
13+
# source1 [source2 source3 ...])
14+
#
15+
# name
16+
# Name of the test (e.g., SwiftASTTest).
17+
#
18+
# IS_TARGET_TEST
19+
# Indicates this is a test for target libraries. Not host library.
20+
# This avoids linking with toolchains stdlib.
21+
#
22+
# source1 ...
23+
# Sources to add into this executable.
824
function(add_swift_unittest test_dirname)
25+
cmake_parse_arguments(ASU
26+
"IS_TARGET_TEST"
27+
""
28+
""
29+
${ARGN})
30+
931
# *NOTE* Even though "add_unittest" does not have llvm in its name, it is a
1032
# function defined by AddLLVM.cmake.
11-
add_unittest(SwiftUnitTests ${test_dirname} ${ARGN})
33+
add_unittest(SwiftUnitTests ${test_dirname} ${ASU_UNPARSED_ARGUMENTS})
1234

1335
set_target_properties(${test_dirname} PROPERTIES LINKER_LANGUAGE CXX)
1436

@@ -89,7 +111,8 @@ function(add_swift_unittest test_dirname)
89111
endif()
90112
endif()
91113

92-
if (SWIFT_SWIFT_PARSER)
114+
if (SWIFT_SWIFT_PARSER AND NOT ASU_IS_TARGET_TEST)
115+
# Link to stdlib the compiler uses.
93116
_add_swift_runtime_link_flags(${test_dirname} "../../lib" "")
94117
set_property(TARGET ${test_dirname} PROPERTY BUILD_WITH_INSTALL_RPATH OFF)
95118
endif()

Diff for: cmake/modules/SwiftImplicitImport.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function(swift_supports_implicit_module module_name out_var)
66
"${CMAKE_Swift_COMPILER}"
77
-Xfrontend -disable-implicit-${module_name}-module-import
88
-Xfrontend -parse-stdlib
9-
-c - -o /dev/null
9+
-parse -
1010
INPUT_FILE
1111
"${CMAKE_BINARY_DIR}/tmp/empty-check-${module_name}.swift"
1212
OUTPUT_QUIET ERROR_QUIET

Diff for: cmake/modules/SwiftStripBuilderRpath.cmake

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
set(SWIFT_SET_RPATH_SCRIPT_FILE "${CMAKE_CURRENT_LIST_FILE}")
2+
3+
function(swift_get_set_rpath_script_file out_var)
4+
set(${out_var} "${SWIFT_SET_RPATH_SCRIPT_FILE}" PARENT_SCOPE)
5+
endfunction()
6+
7+
# Actual RPATH_SET operation to the file.
8+
function(_swift_set_rpath_impl file new_rpath)
9+
# NOTE: RPATH_SET is not documented, and works only for ELF and XCOFF.
10+
file(RPATH_SET FILE "${file}" NEW_RPATH "${new_rpath}")
11+
endfunction()
12+
13+
# For 'install(SCRIPT <script> CODE swift_set_rpath(...)'.
14+
function(_swift_file_set_rpath_installed file new_rpath)
15+
set(DESTDIR $ENV{DESTDIR})
16+
if(NOT IS_ABSOLUTE "${file}")
17+
string(PREPEND file "${CMAKE_INSTALL_PREFIX}/")
18+
endif()
19+
string(PREPEND file "${DESTDIR}")
20+
_swift_set_rpath_impl("${file}" "${new_rpath}")
21+
endfunction()
22+
23+
# Add 'install' script that set runtime path to the specified file.
24+
function(swift_install_file_set_rpath file install_rpath component)
25+
if(NOT(SWIFT_HOST_VARIANT_SDK STREQUAL "LINUX"))
26+
return()
27+
endif()
28+
if((NOT SWIFT_SWIFT_PARSER) AND NOT(BOOTSTRAPPING_MODE STREQUAL "HOSTTOOLS"))
29+
return()
30+
endif()
31+
32+
swift_get_set_rpath_script_file(script)
33+
34+
swift_install_in_component(
35+
SCRIPT "${script}"
36+
CODE "_swift_file_set_rpath_installed(\"${file}\" \"${install_rpath}\")"
37+
COMPONENT ${component}
38+
)
39+
endfunction()
40+
41+
# Add 'install' script that set runtime path to the target but only startinig with '$ORIGIN'
42+
function(swift_install_strip_builder_rpath)
43+
cmake_parse_arguments(RPATH
44+
""
45+
"DESTINATION;COMPONENT"
46+
"TARGETS"
47+
${ARGN})
48+
49+
foreach(target ${RPATH_TARGETS})
50+
# Filter out RPATHs *not* starting with $ORIGIN
51+
set(stripped_rpaths)
52+
get_target_property(install_rpaths ${target} INSTALL_RPATH)
53+
foreach(path ${install_rpaths})
54+
if (path MATCHES "^\\$ORIGIN")
55+
list(APPEND stripped_rpaths "${path}")
56+
endif()
57+
endforeach()
58+
59+
list(JOIN stripped_rpaths ":" install_rpath_str)
60+
swift_install_file_set_rpath(
61+
"${RPATH_DESTINATION}/$<TARGET_FILE_NAME:${target}>"
62+
"${install_rpath_str}"
63+
${RPATH_COMPONENT}
64+
)
65+
endforeach()
66+
endfunction()
67+
68+
# For 'cmake -P <scirpt>'.
69+
if (SWIFT_SET_RPATH_FILE AND SWIFT_SET_RPATH_NEW_RPATH)
70+
_swift_set_rpath_impl("${SWIFT_SET_RPATH_FILE}" "${SWIFT_SET_RPATH_NEW_RPATH}")
71+
endif()

Diff for: lib/CMakeLists.txt

+39-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ if (SWIFT_SWIFT_PARSER)
3333
list(TRANSFORM SWIFT_SYNTAX_MODULES PREPEND "SwiftSyntax::"
3434
OUTPUT_VARIABLE SWIFT_SYNTAX_TARGETS)
3535

36-
set(SWIFT_SYNTAX_LIBRARIES_SOURCE_DIR
36+
set(SWIFT_SYNTAX_LIBRARIES_BUILD_DIR
3737
"${SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR}/lib/swift/host")
3838
set(SWIFT_HOST_LIBRARIES_DEST_DIR
3939
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/swift/host")
@@ -53,17 +53,46 @@ if (SWIFT_SWIFT_PARSER)
5353
# Copy over all of the shared libraries from earlyswiftsyntax so they can
5454
# be found via RPATH.
5555
foreach (sharedlib ${SWIFT_SYNTAX_SHARED_LIBRARIES})
56+
set(add_origin_rpath)
57+
if(SWIFT_HOST_VARIANT_SDK STREQUAL "LINUX")
58+
get_filename_component(swift_bin_dir ${CMAKE_Swift_COMPILER} DIRECTORY)
59+
get_filename_component(swift_dir ${swift_bin_dir} DIRECTORY)
60+
set(host_lib_dir "${swift_dir}/lib/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
61+
62+
# At runtime, use swiftCore in the current toolchain.
63+
64+
swift_get_set_rpath_script_file(setrpath_command)
65+
set(add_origin_rpath COMMAND ${CMAKE_COMMAND}
66+
"-DSWIFT_SET_RPATH_FILE=${SWIFT_HOST_LIBRARIES_DEST_DIR}/${sharedlib}"
67+
"-DSWIFT_SET_RPATH_NEW_RPATH='$$ORIGIN:$$ORIGIN/../${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}:${host_lib_dir}'"
68+
-P "${setrpath_command}"
69+
)
70+
endif()
71+
5672
add_custom_command(
5773
OUTPUT "${SWIFT_HOST_LIBRARIES_DEST_DIR}/${sharedlib}"
58-
DEPENDS "${SWIFT_SYNTAX_LIBRARIES_SOURCE_DIR}/${sharedlib}"
59-
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SWIFT_SYNTAX_LIBRARIES_SOURCE_DIR}/${sharedlib} ${SWIFT_HOST_LIBRARIES_DEST_DIR}/${sharedlib}
74+
DEPENDS "${SWIFT_SYNTAX_LIBRARIES_BUILD_DIR}/${sharedlib}"
75+
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SWIFT_SYNTAX_LIBRARIES_BUILD_DIR}/${sharedlib} ${SWIFT_HOST_LIBRARIES_DEST_DIR}/${sharedlib}
76+
${add_origin_rpath}
6077
)
6178

6279
add_custom_target(copy_swiftSyntaxLibrary_${sharedlib}
6380
DEPENDS "${SWIFT_HOST_LIBRARIES_DEST_DIR}/${sharedlib}"
6481
COMMENT "Copying ${sharedlib}"
6582
)
6683

84+
swift_install_in_component(
85+
FILES "${SWIFT_HOST_LIBRARIES_DEST_DIR}/${sharedlib}"
86+
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/host"
87+
COMPONENT compiler
88+
)
89+
90+
swift_install_file_set_rpath(
91+
"lib${LLVM_LIBDIR_SUFFIX}/swift/host/${sharedlib}"
92+
"$ORIGIN:$ORIGIN/../${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}"
93+
compiler
94+
)
95+
6796
add_dependencies(swiftSyntaxLibraries copy_swiftSyntaxLibrary_${sharedlib})
6897
endforeach()
6998

@@ -76,7 +105,7 @@ if (SWIFT_SWIFT_PARSER)
76105
foreach(module_dir ${SWIFT_SYNTAX_MODULE_DIRS})
77106
# Find all of the source module files.
78107
file(GLOB module_files
79-
"${SWIFT_SYNTAX_LIBRARIES_SOURCE_DIR}/${module_dir}/*.swiftinterface")
108+
"${SWIFT_SYNTAX_LIBRARIES_BUILD_DIR}/${module_dir}/*.swiftinterface")
80109

81110
# Determine the destination module files.
82111
set(dest_module_files)
@@ -98,6 +127,12 @@ if (SWIFT_SWIFT_PARSER)
98127
COMMENT "Copying ${module_dir}"
99128
)
100129

130+
swift_install_in_component(
131+
FILES ${dest_module_files}
132+
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/host/${module_dir}"
133+
COMPONENT compiler
134+
)
135+
101136
add_dependencies(swiftSyntaxLibraries copy_swiftSyntaxModule_${module_dir})
102137
endforeach()
103138

Diff for: lib/Macros/CMakeLists.txt

+23-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ function(add_swift_macro_library name)
3131
# Add the library.
3232
add_pure_swift_host_library(${name} SHARED ${ASML_SOURCES})
3333

34+
# Add rpath to 'lib/{platform}'
35+
file(RELATIVE_PATH relpath_to_lib
36+
"${SWIFT_HOST_PLUGINS_DEST_DIR}"
37+
"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
38+
)
39+
_set_pure_swift_link_flags(${name} "${relpath_to_lib}")
40+
41+
# Add rpath to 'lib/host'
42+
if(SWIFT_HOST_VARIANT_SDK STREQUAL "LINUX")
43+
set_property(TARGET ${name}
44+
APPEND PROPERTY INSTALL_RPATH "$ORIGIN/..")
45+
endif()
46+
3447
# If we don't have the Swift swift parser, bail out, because the above
3548
# add_pure_swift_host_library did nothing.
3649
if (NOT SWIFT_SWIFT_PARSER)
@@ -44,14 +57,22 @@ function(add_swift_macro_library name)
4457
LIBRARY_OUTPUT_DIRECTORY "${SWIFT_HOST_PLUGINS_DEST_DIR}"
4558
)
4659

60+
set(destination_dir "lib${LLVM_LIBDIR_SUFFIX}/swift/host/plugins")
61+
4762
swift_install_in_component(TARGETS ${name}
4863
LIBRARY
49-
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/host/plugins"
64+
DESTINATION "${destination_dir}"
5065
COMPONENT compiler
5166
ARCHIVE
52-
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift/host/plugins"
67+
DESTINATION "${destination_dir}"
5368
COMPONENT compiler)
5469

70+
swift_install_strip_builder_rpath(
71+
TARGETS ${name}
72+
DESTINATION "${destination_dir}"
73+
COMPONENT compiler
74+
)
75+
5576
# Export this macro plugin target.
5677
set_property(GLOBAL APPEND PROPERTY SWIFT_MACRO_PLUGINS ${name})
5778
endfunction()

Diff for: lib/SwiftDemangle/CMakeLists.txt

+7
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@ swift_install_in_component(TARGETS swiftDemangle
1717
ARCHIVE
1818
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}"
1919
COMPONENT compiler)
20+
21+
22+
swift_install_strip_builder_rpath(
23+
TARGETS swiftDemangle
24+
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}"
25+
COMPONENT compiler
26+
)

0 commit comments

Comments
 (0)