mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
For hosts that have a swiftly-managed Swift compiler, we could not bootstrap using those tools, because of some hardcoded assumptions about where the `/lib` directory lives, relative to the `/bin` directory that contains the detected `swiftc`. This patch adds specific support for detecting when the `swiftc` is coming from a swiftly install and uses the correct paths. I've tested this patch on my Linux machine that has swiftly 1.0.1, with the Swift 6.1.2 toolchain.
251 lines
8.4 KiB
CMake
251 lines
8.4 KiB
CMake
include(CMakeParseArguments)
|
|
|
|
function(precondition var)
|
|
cmake_parse_arguments(
|
|
PRECONDITION # prefix
|
|
"NEGATE" # options
|
|
"MESSAGE" # single-value args
|
|
"" # multi-value args
|
|
${ARGN})
|
|
|
|
if (PRECONDITION_NEGATE)
|
|
if (${var})
|
|
if (PRECONDITION_MESSAGE)
|
|
message(FATAL_ERROR "Error! ${PRECONDITION_MESSAGE}")
|
|
else()
|
|
message(FATAL_ERROR "Error! Variable ${var} is true or not empty. The value of ${var} is ${${var}}.")
|
|
endif()
|
|
endif()
|
|
else()
|
|
if (NOT ${var})
|
|
if (PRECONDITION_MESSAGE)
|
|
message(FATAL_ERROR "Error! ${PRECONDITION_MESSAGE}")
|
|
else()
|
|
message(FATAL_ERROR "Error! Variable ${var} is false, empty or not set.")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
endfunction()
|
|
|
|
# Assert is 'NOT ${LHS} ${OP} ${RHS}' is true.
|
|
function(precondition_binary_op OP LHS RHS)
|
|
cmake_parse_arguments(
|
|
PRECONDITIONBINOP # prefix
|
|
"NEGATE" # options
|
|
"MESSAGE" # single-value args
|
|
"" # multi-value args
|
|
${ARGN})
|
|
|
|
if (PRECONDITIONBINOP_NEGATE)
|
|
if (${LHS} ${OP} ${RHS})
|
|
if (PRECONDITIONBINOP_MESSAGE)
|
|
message(FATAL_ERROR "Error! ${PRECONDITIONBINOP_MESSAGE}")
|
|
else()
|
|
message(FATAL_ERROR "Error! ${LHS} ${OP} ${RHS} is true!")
|
|
endif()
|
|
endif()
|
|
else()
|
|
if (NOT ${LHS} ${OP} ${RHS})
|
|
if (PRECONDITIONBINOP_MESSAGE)
|
|
message(FATAL_ERROR "Error! ${PRECONDITIONBINOP_MESSAGE}")
|
|
else()
|
|
message(FATAL_ERROR "Error! ${LHS} ${OP} ${RHS} is false!")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
endfunction()
|
|
|
|
# Translate a yes/no variable to the presence of a given string in a
|
|
# variable.
|
|
#
|
|
# Usage:
|
|
# translate_flag(is_set flag_name var_name)
|
|
#
|
|
# If is_set is true, sets ${var_name} to ${flag_name}. Otherwise,
|
|
# unsets ${var_name}.
|
|
function(translate_flag is_set flag_name var_name)
|
|
if(${is_set})
|
|
set("${var_name}" "${flag_name}" PARENT_SCOPE)
|
|
else()
|
|
set("${var_name}" "" PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
macro(translate_flags prefix options)
|
|
foreach(var ${options})
|
|
translate_flag("${${prefix}_${var}}" "${var}" "${prefix}_${var}_keyword")
|
|
endforeach()
|
|
endmacro()
|
|
|
|
# Set ${outvar} to ${${invar}}, asserting if ${invar} is not set.
|
|
function(precondition_translate_flag invar outvar)
|
|
precondition(${invar})
|
|
set(${outvar} "${${invar}}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(get_bootstrapping_path path_var orig_path bootstrapping)
|
|
if("${bootstrapping}" STREQUAL "")
|
|
set(${path_var} ${orig_path} PARENT_SCOPE)
|
|
else()
|
|
file(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${orig_path})
|
|
set(${path_var} "${CMAKE_BINARY_DIR}/bootstrapping${bootstrapping}/${relative_path}" PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
# When building the stdlib in bootstrapping, return the swift library path
|
|
# from the previous bootstrapping stage.
|
|
function(get_bootstrapping_swift_lib_dir bs_lib_dir bootstrapping)
|
|
set(bs_lib_dir "")
|
|
if(BOOTSTRAPPING_MODE STREQUAL "BOOTSTRAPPING")
|
|
set(lib_dir
|
|
"${SWIFTLIB_DIR}/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
|
|
# If building the stdlib with bootstrapping, the compiler has to pick up
|
|
# the swift libraries of the previous bootstrapping level (because in the
|
|
# current lib-directory they are not built yet.
|
|
if ("${bootstrapping}" STREQUAL "1")
|
|
get_bootstrapping_path(bs_lib_dir ${lib_dir} "0")
|
|
elseif("${bootstrapping}" STREQUAL "")
|
|
get_bootstrapping_path(bs_lib_dir ${lib_dir} "1")
|
|
endif()
|
|
elseif(BOOTSTRAPPING_MODE STREQUAL "HOSTTOOLS")
|
|
if(SWIFT_HOST_VARIANT_SDK MATCHES "LINUX|ANDROID|OPENBSD|FREEBSD")
|
|
# Compiler's INSTALL_RPATH is set to libs in the build directory
|
|
# For building stdlib, use stdlib in the builder's resource directory
|
|
# because the runtime may not be built yet.
|
|
# FIXME: This assumes the ABI hasn't changed since the builder.
|
|
get_filename_component(swift_bin_dir ${CMAKE_Swift_COMPILER} DIRECTORY)
|
|
get_filename_component(swift_dir ${swift_bin_dir} DIRECTORY)
|
|
|
|
# Detect and handle swiftly-managed hosts.
|
|
if(swift_bin_dir MATCHES ".*/swiftly/bin")
|
|
execute_process(COMMAND swiftly use --print-location
|
|
OUTPUT_VARIABLE swiftly_dir
|
|
ERROR_VARIABLE err)
|
|
if(err)
|
|
message(SEND_ERROR "Failed to find swiftly Swift compiler")
|
|
endif()
|
|
string(STRIP "${swiftly_dir}" swiftly_dir)
|
|
set(swift_dir "${swiftly_dir}/usr")
|
|
endif()
|
|
|
|
set(bs_lib_dir "${swift_dir}/lib/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
|
|
endif()
|
|
endif()
|
|
set(bs_lib_dir ${bs_lib_dir} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(is_build_type_optimized build_type result_var_name)
|
|
if("${build_type}" STREQUAL "Debug")
|
|
set("${result_var_name}" FALSE PARENT_SCOPE)
|
|
elseif("${build_type}" STREQUAL "RelWithDebInfo" OR
|
|
"${build_type}" STREQUAL "Release" OR
|
|
"${build_type}" STREQUAL "MinSizeRel")
|
|
set("${result_var_name}" TRUE PARENT_SCOPE)
|
|
else()
|
|
message(FATAL_ERROR "Unknown build type: ${build_type}")
|
|
endif()
|
|
endfunction()
|
|
|
|
function(is_build_type_with_debuginfo build_type result_var_name)
|
|
if("${build_type}" STREQUAL "Debug" OR
|
|
"${build_type}" STREQUAL "RelWithDebInfo")
|
|
set("${result_var_name}" TRUE PARENT_SCOPE)
|
|
elseif("${build_type}" STREQUAL "Release" OR
|
|
"${build_type}" STREQUAL "MinSizeRel")
|
|
set("${result_var_name}" FALSE PARENT_SCOPE)
|
|
else()
|
|
message(FATAL_ERROR "Unknown build type: ${build_type}")
|
|
endif()
|
|
endfunction()
|
|
|
|
# Set variable to value if value is not null or false. Otherwise set variable to
|
|
# default_value.
|
|
function(set_with_default variable value)
|
|
cmake_parse_argument(
|
|
SWD
|
|
""
|
|
"DEFAULT"
|
|
"" ${ARGN})
|
|
precondition(SWD_DEFAULT
|
|
MESSAGE "Must specify a default argument")
|
|
if (value)
|
|
set(${variable} ${value} PARENT_SCOPE)
|
|
else()
|
|
set(${variable} ${SWD_DEFAULT} PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
function(swift_create_post_build_symlink target)
|
|
set(options IS_DIRECTORY)
|
|
set(oneValueArgs SOURCE DESTINATION WORKING_DIRECTORY COMMENT)
|
|
cmake_parse_arguments(CS
|
|
"${options}"
|
|
"${oneValueArgs}"
|
|
""
|
|
${ARGN})
|
|
|
|
if(CS_IS_DIRECTORY)
|
|
set(cmake_symlink_option "${SWIFT_COPY_OR_SYMLINK_DIR}")
|
|
else()
|
|
set(cmake_symlink_option "${SWIFT_COPY_OR_SYMLINK}")
|
|
endif()
|
|
|
|
add_custom_command(TARGET "${target}" POST_BUILD
|
|
COMMAND
|
|
"${CMAKE_COMMAND}" "-E" "${cmake_symlink_option}"
|
|
"${CS_SOURCE}"
|
|
"${CS_DESTINATION}"
|
|
WORKING_DIRECTORY "${CS_WORKING_DIRECTORY}"
|
|
COMMENT "${CS_COMMENT}")
|
|
endfunction()
|
|
|
|
# Once swift-frontend is built, if the standalone (early) swift-driver has been built,
|
|
# we create a `swift-driver` symlink adjacent to the `swift` and `swiftc` executables
|
|
# to ensure that `swiftc` forwards to the standalone driver when invoked.
|
|
function(swift_create_early_driver_copies target)
|
|
set(SWIFT_EARLY_SWIFT_DRIVER_BUILD "" CACHE PATH "Path to early swift-driver build")
|
|
|
|
if(NOT SWIFT_EARLY_SWIFT_DRIVER_BUILD)
|
|
return()
|
|
endif()
|
|
|
|
if(EXISTS ${SWIFT_EARLY_SWIFT_DRIVER_BUILD}/swift-driver${CMAKE_EXECUTABLE_SUFFIX})
|
|
message(STATUS "Creating early SwiftDriver symlinks")
|
|
|
|
# Use `configure_file` instead of `file(COPY ...)` to establish a
|
|
# dependency. Further changes to `swift-driver` will cause it to be copied
|
|
# over.
|
|
configure_file(${SWIFT_EARLY_SWIFT_DRIVER_BUILD}/swift-driver${CMAKE_EXECUTABLE_SUFFIX}
|
|
${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-driver${CMAKE_EXECUTABLE_SUFFIX}
|
|
COPYONLY)
|
|
configure_file(${SWIFT_EARLY_SWIFT_DRIVER_BUILD}/swift-help${CMAKE_EXECUTABLE_SUFFIX}
|
|
${SWIFT_RUNTIME_OUTPUT_INTDIR}/swift-help${CMAKE_EXECUTABLE_SUFFIX}
|
|
COPYONLY)
|
|
else()
|
|
message(STATUS "Not creating early SwiftDriver symlinks (swift-driver not found)")
|
|
endif()
|
|
endfunction()
|
|
|
|
function(dump_swift_vars)
|
|
set(SWIFT_STDLIB_GLOBAL_CMAKE_CACHE)
|
|
get_cmake_property(variableNames VARIABLES)
|
|
foreach(variableName ${variableNames})
|
|
if(variableName MATCHES "^SWIFT")
|
|
set(SWIFT_STDLIB_GLOBAL_CMAKE_CACHE "${SWIFT_STDLIB_GLOBAL_CMAKE_CACHE}set(${variableName} \"${${variableName}}\")\n")
|
|
message("set(${variableName} \"${${variableName}}\")")
|
|
endif()
|
|
endforeach()
|
|
endfunction()
|
|
|
|
function(is_sdk_requested name result_var_name)
|
|
if("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${name}")
|
|
set("${result_var_name}" "TRUE" PARENT_SCOPE)
|
|
else()
|
|
if("${name}" IN_LIST SWIFT_SDKS)
|
|
set("${result_var_name}" "TRUE" PARENT_SCOPE)
|
|
else()
|
|
set("${result_var_name}" "FALSE" PARENT_SCOPE)
|
|
endif()
|
|
endif()
|
|
endfunction()
|