diff --git a/CMakeLists.txt b/CMakeLists.txt index 753ff535707..b8e072d218c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -794,6 +794,7 @@ include(SwiftConfigureSDK) include(SwiftComponents) include(SwiftList) include(AddPureSwift) +include(SwiftStripBuilderRpath) # Configure swift include, install, build components. swift_configure_components() diff --git a/SwiftCompilerSources/CMakeLists.txt b/SwiftCompilerSources/CMakeLists.txt index 4fbd4fca9e5..138d208d9a3 100644 --- a/SwiftCompilerSources/CMakeLists.txt +++ b/SwiftCompilerSources/CMakeLists.txt @@ -235,7 +235,7 @@ else() # # step 1: generate a dummy source file, which just includes all headers # defined in include/swift/module.modulemap - file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp" + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp.tmp" " #include \"Basic/BridgedSwiftObject.h\" #include \"Basic/BasicBridging.h\" @@ -251,6 +251,12 @@ else() #include \"Parse/RegexParserBridging.h\" ") + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp.tmp" + "${CMAKE_CURRENT_BINARY_DIR}/HeaderDependencies.cpp" + ) # step 2: build a library containing that source file. This library depends on all the included header files. # The swift modules can now depend on that target. diff --git a/cmake/modules/AddPureSwift.cmake b/cmake/modules/AddPureSwift.cmake index 8d26200a551..401fdeb4e46 100644 --- a/cmake/modules/AddPureSwift.cmake +++ b/cmake/modules/AddPureSwift.cmake @@ -65,6 +65,27 @@ function(_add_host_swift_compile_options name) _add_host_variant_swift_sanitizer_flags(${name}) endfunction() +function(_set_pure_swift_link_flags name relpath_to_lib_dir) + if(SWIFT_HOST_VARIANT_SDK STREQUAL "LINUX") + # Don't add builder's stdlib RPATH automatically, because we want to *de-prioritize* it. + target_compile_options(${name} PRIVATE + $<$:-no-toolchain-stdlib-rpath> + ) + + get_filename_component(swift_bin_dir ${CMAKE_Swift_COMPILER} DIRECTORY) + get_filename_component(swift_dir ${swift_bin_dir} DIRECTORY) + set(host_lib_dir "${swift_dir}/lib/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}") + + set_property(TARGET ${name} + APPEND PROPERTY INSTALL_RPATH + # At runtime, use swiftCore in the current toolchain. + "$ORIGIN/${relpath_to_lib_dir}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}" + # But before building the stdlib with the tool, use the builder libs. This should be removed in install time. + "${host_lib_dir}") + + endif() +endfunction() + # Add a new "pure" Swift host library. # # "Pure" Swift host libraries can only contain Swift code, and will be built @@ -266,6 +287,7 @@ function(add_pure_swift_host_tool name) # Create the library. add_executable(${name} ${APSHT_SOURCES}) _add_host_swift_compile_options(${name}) + _set_pure_swift_link_flags(${name} "../lib") if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS) set_property(TARGET ${name} diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index d4f19d1e2d3..1f003033903 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -548,10 +548,14 @@ function(_add_swift_runtime_link_flags target relpath_to_lib_dir bootstrapping) target_link_libraries(${target} PRIVATE "swiftCore") target_link_directories(${target} PRIVATE ${host_lib_dir}) + + # At runtime, use swiftCore in the current toolchain. + # FIXME: This assumes the ABI hasn't changed since the builder. + set(swift_runtime_rpath "$ORIGIN/${relpath_to_lib_dir}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}") + if(ASRLF_BOOTSTRAPPING_MODE STREQUAL "HOSTTOOLS") - set(swift_runtime_rpath "${host_lib_dir}") - else() - set(swift_runtime_rpath "$ORIGIN/${relpath_to_lib_dir}/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}") + # But before building the stdlib with the tool, use the builder libs. This should be removed in install time. + list(APPEND swift_runtime_rpath "${host_lib_dir}") endif() elseif(ASRLF_BOOTSTRAPPING_MODE STREQUAL "BOOTSTRAPPING") @@ -576,9 +580,6 @@ function(_add_swift_runtime_link_flags target relpath_to_lib_dir bootstrapping) endif() if(SWIFT_SWIFT_PARSER) - # Make sure we can find the early SwiftSyntax libraries. - target_link_directories(${target} PRIVATE "${SWIFT_PATH_TO_EARLYSWIFTSYNTAX_BUILD_DIR}/lib/swift/host") - # For the "end step" of bootstrapping configurations, we need to be # able to fall back to the SDK directory for libswiftCore et al. if (BOOTSTRAPPING_MODE MATCHES "BOOTSTRAPPING.*") @@ -967,7 +968,14 @@ function(add_swift_host_tool executable) swift_install_in_component(TARGETS ${executable} RUNTIME DESTINATION bin - COMPONENT ${ASHT_SWIFT_COMPONENT}) + COMPONENT ${ASHT_SWIFT_COMPONENT} + ) + + swift_install_strip_builder_rpath( + TARGETS ${executable} + DESTINATION bin + COMPONENT ${ASHT_SWIFT_COMPONENT} + ) swift_is_installing_component(${ASHT_SWIFT_COMPONENT} is_installing) endif() diff --git a/cmake/modules/AddSwiftUnittests.cmake b/cmake/modules/AddSwiftUnittests.cmake index a4573981c22..45acb9bf106 100644 --- a/cmake/modules/AddSwiftUnittests.cmake +++ b/cmake/modules/AddSwiftUnittests.cmake @@ -5,10 +5,32 @@ add_custom_target(SwiftUnitTests) set_target_properties(SwiftUnitTests PROPERTIES FOLDER "Tests") +# Add a new Swift unit test executable. +# +# Usage: +# add_swift_unittest(name +# [IS_TARGET_TEST] +# source1 [source2 source3 ...]) +# +# name +# Name of the test (e.g., SwiftASTTest). +# +# IS_TARGET_TEST +# Indicates this is a test for target libraries. Not host library. +# This avoids linking with toolchains stdlib. +# +# source1 ... +# Sources to add into this executable. function(add_swift_unittest test_dirname) + cmake_parse_arguments(ASU + "IS_TARGET_TEST" + "" + "" + ${ARGN}) + # *NOTE* Even though "add_unittest" does not have llvm in its name, it is a # function defined by AddLLVM.cmake. - add_unittest(SwiftUnitTests ${test_dirname} ${ARGN}) + add_unittest(SwiftUnitTests ${test_dirname} ${ASU_UNPARSED_ARGUMENTS}) set_target_properties(${test_dirname} PROPERTIES LINKER_LANGUAGE CXX) @@ -89,7 +111,8 @@ function(add_swift_unittest test_dirname) endif() endif() - if (SWIFT_SWIFT_PARSER) + if (SWIFT_SWIFT_PARSER AND NOT ASU_IS_TARGET_TEST) + # Link to stdlib the compiler uses. _add_swift_runtime_link_flags(${test_dirname} "../../lib" "") set_property(TARGET ${test_dirname} PROPERTY BUILD_WITH_INSTALL_RPATH OFF) endif() diff --git a/cmake/modules/SwiftImplicitImport.cmake b/cmake/modules/SwiftImplicitImport.cmake index 50c5e5415ff..3c79357f018 100644 --- a/cmake/modules/SwiftImplicitImport.cmake +++ b/cmake/modules/SwiftImplicitImport.cmake @@ -6,7 +6,7 @@ function(swift_supports_implicit_module module_name out_var) "${CMAKE_Swift_COMPILER}" -Xfrontend -disable-implicit-${module_name}-module-import -Xfrontend -parse-stdlib - -c - -o /dev/null + -parse - INPUT_FILE "${CMAKE_BINARY_DIR}/tmp/empty-check-${module_name}.swift" OUTPUT_QUIET ERROR_QUIET diff --git a/cmake/modules/SwiftStripBuilderRpath.cmake b/cmake/modules/SwiftStripBuilderRpath.cmake new file mode 100644 index 00000000000..8df406b0388 --- /dev/null +++ b/cmake/modules/SwiftStripBuilderRpath.cmake @@ -0,0 +1,71 @@ +set(SWIFT_SET_RPATH_SCRIPT_FILE "${CMAKE_CURRENT_LIST_FILE}") + +function(swift_get_set_rpath_script_file out_var) + set(${out_var} "${SWIFT_SET_RPATH_SCRIPT_FILE}" PARENT_SCOPE) +endfunction() + +# Actual RPATH_SET operation to the file. +function(_swift_set_rpath_impl file new_rpath) + # NOTE: RPATH_SET is not documented, and works only for ELF and XCOFF. + file(RPATH_SET FILE "${file}" NEW_RPATH "${new_rpath}") +endfunction() + +# For 'install(SCRIPT