From 2780b523791d66a5f7b95d664ba285a51801dfef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Rodr=C3=ADguez=20Troiti=C3=B1o?= Date: Thu, 30 Nov 2023 13:55:49 -0800 Subject: [PATCH] [cmake] Allow overriding SwiftCompilerSources arguments from CMake. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The calculated arguments for compiling the SwiftCompilerSources works in the cases where the sysroot of the machine building the code is `/` or can be provided as a single directory in `SWIFT_SDK___PATH`. For some cases in which a sysroot is split into multiple directories or in some cross-compiling scenarios where the SDK layout is beyond our control, we can provide more flexibility in the build system. The changes in this commit moves the calculations around the SDK and libc++ outside the `add_swift_compiler_modules_library`, since they do not depend on the inputs. Some calculations relative to `-resource-dir` depend on the Swift compiler path, which cannot be moved outside the function. The calculations outside the function are stored in a cached variable, which is later used in the function. If the need arise, anyone can provide a custom value for that variable in their CMake invocation or cache files adapted for their specific case and override the automatically calculated default. I also rewrote a couple of `set(list ${list} …)` into `list(APPEND list …)`. This should be NFC for the Swift CI, because no value of `SWIFT_COMPILER_SOURCES_SDK_FLAGS` is provided, and the default should be the same value as before. --- SwiftCompilerSources/CMakeLists.txt | 53 ++++++++++++++++++----------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/SwiftCompilerSources/CMakeLists.txt b/SwiftCompilerSources/CMakeLists.txt index e46a2ad4c1b1a..f6b755af49f8f 100644 --- a/SwiftCompilerSources/CMakeLists.txt +++ b/SwiftCompilerSources/CMakeLists.txt @@ -59,7 +59,33 @@ function(swift_compiler_sources module) set(target_name "SwiftModule${module}") set_property(TARGET "SwiftModule${module}" APPEND PROPERTY SOURCES ${sources}) endfunction() - + +# Allow the override of the flags used to define the SDK used to compile the +# Swift compiler sources from the CMake configuration (command line or cache +# files). This allows supporting complicated sysroots and some cross-compilation +# scenarios. +set(SWIFT_COMPILER_SOURCES_SDK_FLAGS_default) +if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS) + set(sdk_path "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}") + list(APPEND SWIFT_COMPILER_SOURCES_SDK_FLAGS_default "-sdk" "${sdk_path}") + if(NOT EXISTS "${sdk_path}/usr/include/c++") + # Darwin SDKs in Xcode 12 or older do not include libc++, which prevents clang from finding libc++ when invoked + # from ClangImporter. This results in build errors. To workaround this, let's explicitly pass the path to libc++ + # to clang. + message(WARNING "Building with an outdated Darwin SDK: libc++ missing from the ${SWIFT_HOST_VARIANT_SDK} SDK. Will use libc++ from the toolchain.") + get_filename_component(absolute_libcxx_path "${CMAKE_C_COMPILER}/../../include/c++/v1" REALPATH) + if (EXISTS "${absolute_libcxx_path}") + list(APPEND SWIFT_COMPILER_SOURCES_SDK_FLAGS_default "-Xcc" "-isystem" "-Xcc" "${absolute_libcxx_path}") + else() + message(ERROR "libc++ not found in the toolchain.") + endif() + endif() +elseif(BOOTSTRAPPING_MODE STREQUAL "CROSSCOMPILE") + list(APPEND SWIFT_COMPILER_SOURCES_SDK_FLAGS_default "-sdk" "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}") +endif() +set(SWIFT_COMPILER_SOURCES_SDK_FLAGS ${SWIFT_COMPILER_SOURCES_SDK_FLAGS_default} + CACHE STRING "Swift flags used to compiler the Swift compiler sources") + # Add a library target for the swift compiler modules. # # Adds targets to compile all swift compiler modules and a target for the @@ -103,35 +129,22 @@ function(add_swift_compiler_modules_library name) get_bootstrapping_path(build_dir ${CMAKE_CURRENT_BINARY_DIR} "${ALS_BOOTSTRAPPING}") - set(sdk_option "") + set(sdk_option ${SWIFT_COMPILER_SOURCES_SDK_FLAGS}) if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS) set(deployment_version "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}") - set(sdk_path "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}") - set(sdk_option "-sdk" "${sdk_path}") if(BOOTSTRAPPING_MODE STREQUAL "CROSSCOMPILE-WITH-HOSTLIBS") # Let the cross-compiled compile don't pick up the compiled stdlib by providing # an (almost) empty resource dir. # The compiler will instead pick up the stdlib from the SDK. get_filename_component(swift_exec_bin_dir ${ALS_SWIFT_EXEC} DIRECTORY) - set(sdk_option ${sdk_option} "-resource-dir" "${swift_exec_bin_dir}/../bootstrapping0/lib/swift") - endif() - if(NOT EXISTS "${sdk_path}/usr/include/c++") - # Darwin SDKs in Xcode 12 or older do not include libc++, which prevents clang from finding libc++ when invoked - # from ClangImporter. This results in build errors. To workaround this, let's explicitly pass the path to libc++ - # to clang. - message(WARNING "Building with an outdated Darwin SDK: libc++ missing from the ${SWIFT_HOST_VARIANT_SDK} SDK. Will use libc++ from the toolchain.") - get_filename_component(absolute_libcxx_path "${CMAKE_C_COMPILER}/../../include/c++/v1" REALPATH) - if (EXISTS "${absolute_libcxx_path}") - set(sdk_option ${sdk_option} "-Xcc" "-isystem" "-Xcc" "${absolute_libcxx_path}") - else() - message(ERROR "libc++ not found in the toolchain.") - endif() + list(APPEND sdk_option "-resource-dir" "${swift_exec_bin_dir}/../bootstrapping0/lib/swift") endif() elseif(BOOTSTRAPPING_MODE STREQUAL "CROSSCOMPILE") - set(sdk_option "-sdk" "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}") get_filename_component(swift_exec_bin_dir ${ALS_SWIFT_EXEC} DIRECTORY) - set(sdk_option ${sdk_option} "-resource-dir" "${swift_exec_bin_dir}/../lib/swift") + # NOTE: prepending allows SWIFT_COMPILER_SOURCES_SDK_FLAGS to override the + # resource directory if needed. + list(PREPEND sdk_option "-resource-dir" "${swift_exec_bin_dir}/../lib/swift") endif() get_versioned_target_triple(target ${SWIFT_HOST_VARIANT_SDK} ${SWIFT_HOST_VARIANT_ARCH} "${deployment_version}") @@ -140,7 +153,7 @@ function(add_swift_compiler_modules_library name) # under `include/swift`. These are either located next to the compiler (in case of open source toolchains) or # in the SDK (in case a Swift compiler from Xcode) get_filename_component(swift_exec_bin_dir ${ALS_SWIFT_EXEC} DIRECTORY) - set(sdk_option ${sdk_option} "-I" "${swift_exec_bin_dir}/../lib" "-I" "${sdk_path}/usr/lib") + list(APPEND sdk_option "-I" "${swift_exec_bin_dir}/../lib" "-I" "${sdk_path}/usr/lib") set(all_obj_files) set(all_module_targets)