Skip to content

Commit 510d66b

Browse files
authored
Merge pull request swiftlang#39461 from eeckstein/libswift-bootstrapping
libswift: bootstrapping build
2 parents 36c2c83 + af71088 commit 510d66b

File tree

26 files changed

+758
-186
lines changed

26 files changed

+758
-186
lines changed

CMakeLists.txt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
cmake_minimum_required(VERSION 3.19.6)
22

3+
4+
# set_property(GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1)
5+
36
# TODO: Fix RPATH usage to be CMP0068 compliant
47
# Disable Policy CMP0068 for CMake 3.9
58
# rdar://37725888
@@ -196,9 +199,13 @@ set(SWIFT_TOOLS_ENABLE_LTO OFF CACHE STRING "Build Swift tools with LTO. One
196199
no effect on the target libraries (the standard library and the runtime).")
197200

198201
# NOTE: We do not currently support building libswift with the Xcode generator.
199-
cmake_dependent_option(SWIFT_TOOLS_ENABLE_LIBSWIFT
200-
"Enable building libswift and linking libswift into the compiler itself." FALSE
201-
"NOT CMAKE_GENERATOR STREQUAL \"Xcode\"" FALSE)
202+
cmake_dependent_option(LIBSWIFT_BUILD_MODE "How to build libswift. Possible values are
203+
OFF: the compiler is built without libswift
204+
HOSTTOOLS: libswift is built with a pre-installed toolchain
205+
BOOTSTRAPPING: libswift is built with a 2-stage bootstrapping process
206+
BOOTSTRAPPING-WITH-HOSTLIBS: libswift is built with a 2-stage bootstrapping process,
207+
but the compiler links against the host system swift libs (macOS only)"
208+
OFF "NOT CMAKE_GENERATOR STREQUAL \"Xcode\"" OFF)
202209

203210
# The following only works with the Ninja generator in CMake >= 3.0.
204211
set(SWIFT_PARALLEL_LINK_JOBS "" CACHE STRING
@@ -589,6 +596,13 @@ set(SWIFT_RUNTIME_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin")
589596
set(SWIFT_LIBRARY_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib")
590597
if("${SWIFT_NATIVE_SWIFT_TOOLS_PATH}" STREQUAL "")
591598
set(SWIFT_NATIVE_SWIFT_TOOLS_PATH "${SWIFT_RUNTIME_OUTPUT_INTDIR}")
599+
set(SWIFT_EXEC_FOR_LIBSWIFT "${CMAKE_Swift_COMPILER}")
600+
elseif(LIBSWIFT_BUILD_MODE STREQUAL "BOOTSTRAPPING" OR LIBSWIFT_BUILD_MODE STREQUAL "BOOTSTRAPPING-WITH-HOSTLIBS")
601+
# If cross-compiling we don't have to bootstrap. We can just use the previously
602+
# built native swiftc to build libswift.
603+
message(STATUS "Building libswift with native host tools instead of bootstrapping")
604+
set(LIBSWIFT_BUILD_MODE "HOSTTOOLS")
605+
set(SWIFT_EXEC_FOR_LIBSWIFT "${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swiftc")
592606
endif()
593607

594608
# This setting causes all CMakeLists.txt to automatically have
@@ -933,7 +947,7 @@ if(SWIFT_INCLUDE_TOOLS)
933947
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
934948
message(STATUS " Assertions: ${LLVM_ENABLE_ASSERTIONS}")
935949
message(STATUS " LTO: ${SWIFT_TOOLS_ENABLE_LTO}")
936-
message(STATUS " libswift: ${SWIFT_TOOLS_ENABLE_LIBSWIFT}")
950+
message(STATUS " libswift: ${LIBSWIFT_BUILD_MODE}")
937951
message(STATUS "")
938952
else()
939953
message(STATUS "Not building host Swift tools")
@@ -1040,6 +1054,9 @@ if(SWIFT_ENABLE_DISPATCH)
10401054
include(Libdispatch)
10411055
endif()
10421056

1057+
add_bootstrapping_target(0)
1058+
add_bootstrapping_target(1)
1059+
10431060
# Add all of the subdirectories, where we actually do work.
10441061

10451062
###############

cmake/modules/AddSwift.cmake

Lines changed: 153 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ function(add_swift_host_library name)
520520
521521
add_library(${name} ${libkind} ${ASHL_SOURCES})
522522
523-
if (ASHL_HAS_LIBSWIFT AND SWIFT_TOOLS_ENABLE_LIBSWIFT)
523+
if (ASHL_HAS_LIBSWIFT AND LIBSWIFT_BUILD_MODE)
524524
# Workaround for a linker crash related to autolinking: rdar://77839981
525525
set_property(TARGET ${name} APPEND_STRING PROPERTY
526526
LINK_FLAGS " -lobjc ")
@@ -722,8 +722,13 @@ endfunction()
722722
# This is a temporary workaround until it's possible to compile libswift with
723723
# cmake's builtin swift support.
724724
function(add_libswift name)
725+
cmake_parse_arguments(ALS
726+
""
727+
"BOOTSTRAPPING;SWIFT_EXEC;DEPENDS"
728+
""
729+
${ARGN})
730+
725731
set(libswift_compile_options
726-
"-target" "x86_64-apple-macosx10.15" # TODO: remove this once #38675 lands.
727732
"-Xfrontend" "-validate-tbd-against-ir=none"
728733
"-Xfrontend" "-enable-cxx-interop")
729734
@@ -733,10 +738,11 @@ function(add_libswift name)
733738
list(APPEND libswift_compile_options "-O" "-cross-module-optimization")
734739
endif()
735740
736-
set(build_dir ${CMAKE_CURRENT_BINARY_DIR})
741+
get_bootstrapping_path(build_dir ${CMAKE_CURRENT_BINARY_DIR} "${ALS_BOOTSTRAPPING}")
737742
738743
if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS)
739-
set(deployment_version "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}")
744+
set(deployment_version "10.15") # TODO: once #38675 lands, replace this with
745+
# set(deployment_version "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}")
740746
endif()
741747
get_versioned_target_triple(target ${SWIFT_HOST_VARIANT_SDK}
742748
${SWIFT_HOST_VARIANT_ARCH} "${deployment_version}")
@@ -748,10 +754,15 @@ function(add_libswift name)
748754
get_target_property(module ${module_target} "module_name")
749755
get_target_property(sources ${module_target} SOURCES)
750756
get_target_property(dependencies ${module_target} "module_depends")
751-
if(dependencies)
752-
list(TRANSFORM dependencies PREPEND "LibSwift")
753-
else()
754-
set(dependencies "")
757+
set(deps, "")
758+
if (dependencies)
759+
foreach(dep_module ${dependencies})
760+
if (DEFINED "${dep_module}_dep_target")
761+
list(APPEND deps "${${dep_module}_dep_target}")
762+
else()
763+
message(FATAL_ERROR "libswift module dependency ${module} -> ${dep_module} not found. Make sure to add modules in dependency order")
764+
endif()
765+
endforeach()
755766
endif()
756767
757768
set(module_obj_file "${build_dir}/${module}.o")
@@ -763,8 +774,8 @@ function(add_libswift name)
763774
# Compile the libswift module into an object file
764775
add_custom_command_target(dep_target OUTPUT ${module_obj_file}
765776
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
766-
DEPENDS ${sources} ${dependencies}
767-
COMMAND ${CMAKE_Swift_COMPILER} "-c" "-o" ${module_obj_file}
777+
DEPENDS ${sources} ${deps} ${ALS_DEPENDS}
778+
COMMAND ${ALS_SWIFT_EXEC} "-c" "-o" ${module_obj_file}
768779
"-sdk" "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}"
769780
"-target" ${target}
770781
"-module-name" ${module} "-emit-module"
@@ -775,8 +786,7 @@ function(add_libswift name)
775786
"-I" "${build_dir}"
776787
COMMENT "Building libswift module ${module}")
777788
778-
add_dependencies(${module_target} ${dep_target})
779-
789+
set("${module}_dep_target" ${dep_target})
780790
endforeach()
781791
782792
# Create a static libswift library containing all module object files.
@@ -792,9 +802,19 @@ macro(add_swift_lib_subdirectory name)
792802
add_llvm_subdirectory(SWIFT LIB ${name})
793803
endmacro()
794804
805+
function(_link_built_compatibility_libs executable)
806+
set(platform ${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR})
807+
target_link_directories(${executable} PRIVATE
808+
${SWIFTLIB_DIR}/${platform})
809+
add_dependencies(${executable}
810+
"swiftCompatibility50-${platform}"
811+
"swiftCompatibility51-${platform}"
812+
"swiftCompatibilityDynamicReplacements-${platform}")
813+
endfunction()
814+
795815
function(add_swift_host_tool executable)
796816
set(options HAS_LIBSWIFT)
797-
set(single_parameter_options SWIFT_COMPONENT)
817+
set(single_parameter_options SWIFT_COMPONENT BOOTSTRAPPING)
798818
set(multiple_parameter_options LLVM_LINK_COMPONENTS)
799819
800820
cmake_parse_arguments(ASHT
@@ -833,76 +853,119 @@ function(add_swift_host_tool executable)
833853
add_dependencies(${executable} ${LLVM_COMMON_DEPENDS})
834854
endif()
835855
856+
if(NOT ${ASHT_BOOTSTRAPPING} STREQUAL "")
857+
# Strip the "-bootstrapping<n>" suffix from the target name to get the base
858+
# executable name.
859+
string(REGEX REPLACE "-bootstrapping.*" "" executable_filename ${executable})
860+
set_target_properties(${executable}
861+
PROPERTIES OUTPUT_NAME ${executable_filename})
862+
endif()
863+
836864
set_target_properties(${executable} PROPERTIES
837865
FOLDER "Swift executables")
838866
if(SWIFT_PARALLEL_LINK_JOBS)
839867
set_target_properties(${executable} PROPERTIES
840868
JOB_POOL_LINK swift_link_job_pool)
841869
endif()
842870
if(${SWIFT_HOST_VARIANT_SDK} IN_LIST SWIFT_DARWIN_PLATFORMS)
871+
872+
# Lists of rpaths that we are going to add to our executables.
873+
#
874+
# Please add each rpath separately below to the list, explaining why you are
875+
# adding it.
876+
set(RPATH_LIST)
877+
843878
# If we found a swift compiler and are going to use swift code in swift
844879
# host side tools but link with clang, add the appropriate -L paths so we
845880
# find all of the necessary swift libraries on Darwin.
846-
if (CMAKE_Swift_COMPILER)
847-
# Add in the toolchain directory so we can grab compatibility libraries
848-
get_filename_component(TOOLCHAIN_BIN_DIR ${CMAKE_Swift_COMPILER} DIRECTORY)
849-
get_filename_component(TOOLCHAIN_LIB_DIR "${TOOLCHAIN_BIN_DIR}/../lib/swift/macosx" ABSOLUTE)
850-
target_link_directories(${executable} PUBLIC ${TOOLCHAIN_LIB_DIR})
881+
if (ASHT_HAS_LIBSWIFT AND LIBSWIFT_BUILD_MODE)
882+
883+
if(LIBSWIFT_BUILD_MODE STREQUAL "HOSTTOOLS")
884+
# Add in the toolchain directory so we can grab compatibility libraries
885+
get_filename_component(TOOLCHAIN_BIN_DIR ${SWIFT_EXEC_FOR_LIBSWIFT} DIRECTORY)
886+
get_filename_component(TOOLCHAIN_LIB_DIR "${TOOLCHAIN_BIN_DIR}/../lib/swift/macosx" ABSOLUTE)
887+
target_link_directories(${executable} PUBLIC ${TOOLCHAIN_LIB_DIR})
888+
889+
# Add in the SDK directory for the host platform.
890+
target_link_directories(${executable} PRIVATE
891+
${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}/usr/lib/swift)
892+
893+
# Include the abi stable system stdlib in our rpath.
894+
list(APPEND RPATH_LIST "/usr/lib/swift")
895+
896+
elseif(LIBSWIFT_BUILD_MODE STREQUAL "BOOTSTRAPPING-WITH-HOSTLIBS")
897+
# Pick up the built libswiftCompatibility<n>.a libraries
898+
_link_built_compatibility_libs(${executable})
899+
900+
# Add in the SDK directory for the host platform.
901+
target_link_directories(${executable} PRIVATE
902+
${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}/usr/lib/swift)
851903
852-
# Add in the SDK directory for the host platform and add an rpath.
904+
# Include the abi stable system stdlib in our rpath.
905+
list(APPEND RPATH_LIST "/usr/lib/swift")
906+
907+
elseif(LIBSWIFT_BUILD_MODE STREQUAL "BOOTSTRAPPING")
908+
# Pick up the built libswiftCompatibility<n>.a libraries
909+
_link_built_compatibility_libs(${executable})
910+
911+
# At build time link against the built swift libraries from the
912+
# previous bootstrapping stage.
913+
get_bootstrapping_swift_lib_dir(bs_lib_dir "${bootstrapping}")
914+
target_link_directories(${executable} PRIVATE ${bs_lib_dir})
915+
916+
# At runtime link against the built swift libraries from the current
917+
# bootstrapping stage.
918+
list(APPEND RPATH_LIST "@executable_path/../lib/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
919+
else()
920+
message(FATAL_ERROR "Unknown LIBSWIFT_BUILD_MODE '${LIBSWIFT_BUILD_MODE}'")
921+
endif()
922+
923+
# Workaround to make lldb happy: we have to explicitly add all libswift modules
924+
# to the linker command line.
925+
set(libswift_ast_path_flags "-Wl")
926+
get_property(modules GLOBAL PROPERTY "libswift_modules")
927+
foreach(module ${modules})
928+
get_target_property(module_file "LibSwift${module}" "module_file")
929+
string(APPEND libswift_ast_path_flags ",-add_ast_path,${module_file}")
930+
endforeach()
931+
932+
set_property(TARGET ${executable} APPEND_STRING PROPERTY
933+
LINK_FLAGS ${libswift_ast_path_flags})
934+
935+
# Workaround for a linker crash related to autolinking: rdar://77839981
936+
set_property(TARGET ${executable} APPEND_STRING PROPERTY
937+
LINK_FLAGS " -lobjc ")
938+
939+
else() # ASHT_HAS_LIBSWIFT AND LIBSWIFT_BUILD_MODE
940+
941+
# TODO: do we really need this? Do any tools which don't link libswift include other swift code?
942+
943+
# Add in the SDK directory for the host platform.
853944
#
854945
# NOTE: We do this /after/ target_link_directorying TOOLCHAIN_LIB_DIR to
855946
# ensure that we first find libraries from the toolchain, rather than from
856-
# the SDK. The reason why this is important is that when we perform a
857-
# stage2 build, this path is into the stage1 build. This is not a pure SDK
858-
# and also contains compatibility libraries. We need to make sure that the
859-
# compiler sees the actual toolchain's compatibility libraries first
860-
# before the just built compability libraries or build errors occur.
947+
# the SDK.
861948
target_link_directories(${executable} PRIVATE
862949
${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}/usr/lib/swift)
863950
864-
if (ASHT_HAS_LIBSWIFT AND SWIFT_TOOLS_ENABLE_LIBSWIFT)
865-
# Workaround to make lldb happy: we have to explicitly add all libswift modules
866-
# to the linker command line.
867-
set(libswift_ast_path_flags "-Wl")
868-
get_property(modules GLOBAL PROPERTY "libswift_modules")
869-
foreach(module ${modules})
870-
get_target_property(module_file "LibSwift${module}" "module_file")
871-
string(APPEND libswift_ast_path_flags ",-add_ast_path,${module_file}")
872-
endforeach()
873-
874-
set_property(TARGET ${executable} APPEND_STRING PROPERTY
875-
LINK_FLAGS ${libswift_ast_path_flags})
876-
877-
# Workaround for a linker crash related to autolinking: rdar://77839981
878-
set_property(TARGET ${executable} APPEND_STRING PROPERTY
879-
LINK_FLAGS " -lobjc ")
880-
endif()
881-
endif()
951+
# We also want to be able to find libraries from the base toolchain
952+
# directory. This is so swiftc can rely on its own host side dylibs that may
953+
# contain swift content.
954+
list(APPEND RPATH_LIST "@executable_path/../lib")
882955
883-
# Lists of rpaths that we are going to add to our executables.
884-
#
885-
# Please add each rpath separately below to the list, explaining why you are
886-
# adding it.
887-
set(RPATH_LIST)
888-
889-
# We also want to be able to find libraries from the base toolchain
890-
# directory. This is so swiftc can rely on its own host side dylibs that may
891-
# contain swift content.
892-
list(APPEND RPATH_LIST "@executable_path/../lib")
893-
894-
# Also include the abi stable system stdlib in our rpath.
895-
list(APPEND RPATH_LIST "/usr/lib/swift")
956+
# Also include the abi stable system stdlib in our rpath.
957+
list(APPEND RPATH_LIST "/usr/lib/swift")
958+
endif()
896959
897960
set_target_properties(${executable} PROPERTIES
898961
BUILD_WITH_INSTALL_RPATH YES
899962
INSTALL_RPATH "${RPATH_LIST}")
900963
901-
elseif(SWIFT_HOST_VARIANT_SDK STREQUAL "LINUX")
902-
if (ASHT_HAS_LIBSWIFT AND SWIFT_TOOLS_ENABLE_LIBSWIFT)
964+
elseif(SWIFT_HOST_VARIANT_SDK STREQUAL "LINUX" AND ASHT_HAS_LIBSWIFT AND LIBSWIFT_BUILD_MODE)
965+
if(LIBSWIFT_BUILD_MODE STREQUAL "HOSTTOOLS")
903966
# At build time and and run time, link against the swift libraries in the
904967
# installed host toolchain.
905-
get_filename_component(swift_bin_dir ${CMAKE_Swift_COMPILER} DIRECTORY)
968+
get_filename_component(swift_bin_dir ${SWIFT_EXEC_FOR_LIBSWIFT} DIRECTORY)
906969
get_filename_component(swift_dir ${swift_bin_dir} DIRECTORY)
907970
set(host_lib_dir "${swift_dir}/lib/swift/linux")
908971
@@ -912,14 +975,36 @@ function(add_swift_host_tool executable)
912975
set_target_properties(${executable} PROPERTIES
913976
BUILD_WITH_INSTALL_RPATH YES
914977
INSTALL_RPATH "${host_lib_dir}")
978+
979+
elseif(LIBSWIFT_BUILD_MODE STREQUAL "BOOTSTRAPPING")
980+
# At build time link against the built swift libraries from the
981+
# previous bootstrapping stage.
982+
get_bootstrapping_swift_lib_dir(bs_lib_dir "${bootstrapping}")
983+
target_link_directories(${executable} PRIVATE ${bs_lib_dir})
984+
985+
# At runtime link against the built swift libraries from the current
986+
# bootstrapping stage.
987+
set_target_properties(${executable} PROPERTIES
988+
BUILD_WITH_INSTALL_RPATH YES
989+
INSTALL_RPATH "$ORIGIN/../lib/swift/${SWIFT_SDK_LINUX_LIB_SUBDIR}")
990+
991+
elseif(LIBSWIFT_BUILD_MODE STREQUAL "BOOTSTRAPPING-WITH-HOSTLIBS")
992+
message(FATAL_ERROR "LIBSWIFT_BUILD_MODE 'BOOTSTRAPPING-WITH-HOSTLIBS' not supported on Linux")
993+
else()
994+
message(FATAL_ERROR "Unknown LIBSWIFT_BUILD_MODE '${LIBSWIFT_BUILD_MODE}'")
915995
endif()
916996
endif()
917997
918998
llvm_update_compile_flags(${executable})
919999
swift_common_llvm_config(${executable} ${ASHT_LLVM_LINK_COMPONENTS})
1000+
1001+
get_bootstrapping_path(out_bin_dir
1002+
${SWIFT_RUNTIME_OUTPUT_INTDIR} "${ASHT_BOOTSTRAPPING}")
1003+
get_bootstrapping_path(out_lib_dir
1004+
${SWIFT_LIBRARY_OUTPUT_INTDIR} "${ASHT_BOOTSTRAPPING}")
9201005
set_output_directory(${executable}
921-
BINARY_DIR ${SWIFT_RUNTIME_OUTPUT_INTDIR}
922-
LIBRARY_DIR ${SWIFT_LIBRARY_OUTPUT_INTDIR})
1006+
BINARY_DIR ${out_bin_dir}
1007+
LIBRARY_DIR ${out_lib_dir})
9231008
9241009
if(SWIFT_HOST_VARIANT_SDK STREQUAL WINDOWS)
9251010
swift_windows_include_for_arch(${SWIFT_HOST_VARIANT_ARCH}
@@ -938,13 +1023,15 @@ function(add_swift_host_tool executable)
9381023
endif()
9391024
endif()
9401025
941-
add_dependencies(${ASHT_SWIFT_COMPONENT} ${executable})
942-
swift_install_in_component(TARGETS ${executable}
943-
RUNTIME
944-
DESTINATION bin
945-
COMPONENT ${ASHT_SWIFT_COMPONENT})
1026+
if(NOT ${ASHT_SWIFT_COMPONENT} STREQUAL "no_component")
1027+
add_dependencies(${ASHT_SWIFT_COMPONENT} ${executable})
1028+
swift_install_in_component(TARGETS ${executable}
1029+
RUNTIME
1030+
DESTINATION bin
1031+
COMPONENT ${ASHT_SWIFT_COMPONENT})
9461032
947-
swift_is_installing_component(${ASHT_SWIFT_COMPONENT} is_installing)
1033+
swift_is_installing_component(${ASHT_SWIFT_COMPONENT} is_installing)
1034+
endif()
9481035
9491036
if(NOT is_installing)
9501037
set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${executable})

0 commit comments

Comments
 (0)