Skip to content

Commit 8c7da8d

Browse files
committed
Refactored host/target SDK detection to support cross-compiling
1 parent f9d2276 commit 8c7da8d

File tree

2 files changed

+134
-100
lines changed

2 files changed

+134
-100
lines changed

CMakeLists.txt

Lines changed: 132 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -386,29 +386,78 @@ function(check_working_std_regex result_var_name)
386386
# Apple operating systems use libc++, which has a working std::regex.
387387
set("${result_var_name}" TRUE PARENT_SCOPE)
388388
else()
389-
# libstdc++ 4.8 has an incomplete std::regex implementation, and crashes
390-
# on many regexes.
391-
# libstdc++ 4.9 works.
392-
set(std_regex_test_source
393-
"
394-
#include <regex>
395-
const std::regex broken_regex{
396-
\"([a]+)\",
397-
std::regex::ECMAScript | std::regex::nosubs};
398-
399-
int main() {}
400-
")
401-
402-
check_cxx_source_runs("${std_regex_test_source}" "${result_var_name}_TEST")
403-
if ("${${result_var_name}_TEST}")
404-
set("${result_var_name}" TRUE PARENT_SCOPE)
405-
else()
389+
if(CMAKE_CROSSCOMPILING)
390+
# Can't run C source when cross-compiling; assume false until we have a static check.
406391
set("${result_var_name}" FALSE PARENT_SCOPE)
392+
else()
393+
# libstdc++ 4.8 has an incomplete std::regex implementation, and crashes
394+
# on many regexes.
395+
# libstdc++ 4.9 works.
396+
set(std_regex_test_source
397+
"
398+
#include <regex>
399+
const std::regex broken_regex{
400+
\"([a]+)\",
401+
std::regex::ECMAScript | std::regex::nosubs};
402+
403+
int main() {}
404+
")
405+
406+
check_cxx_source_runs("${std_regex_test_source}" "${result_var_name}_TEST")
407+
if ("${${result_var_name}_TEST}")
408+
set("${result_var_name}" TRUE PARENT_SCOPE)
409+
else()
410+
set("${result_var_name}" FALSE PARENT_SCOPE)
411+
endif()
407412
endif()
408413
endif()
409414
endfunction()
410415
check_working_std_regex(SWIFT_HAVE_WORKING_STD_REGEX)
411416

417+
# If SWIFT_HOST_VARIANT_SDK not given, try to detect from the CMAKE_SYSTEM_NAME.
418+
if(SWIFT_HOST_VARIANT_SDK)
419+
set(SWIFT_HOST_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}")
420+
else()
421+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
422+
set(SWIFT_HOST_VARIANT_SDK_default "LINUX")
423+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
424+
set(SWIFT_HOST_VARIANT_SDK_default "FREEBSD")
425+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
426+
set(SWIFT_HOST_VARIANT_SDK_default "CYGWIN")
427+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
428+
set(SWIFT_HOST_VARIANT_SDK_default "OSX")
429+
else()
430+
message(FATAL_ERROR "Unable to detect SDK for host system: ${CMAKE_SYSTEM_NAME}")
431+
endif()
432+
endif()
433+
434+
# If SWIFT_HOST_VARIANT_ARCH not given, try to detect from the CMAKE_SYSTEM_PROCESSOR.
435+
if(SWIFT_HOST_VARIANT_ARCH)
436+
set(SWIFT_HOST_VARIANT_ARCH_default, "${SWIFT_HOST_VARIANT_ARCH}")
437+
else()
438+
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
439+
set(SWIFT_HOST_VARIANT_ARCH_default "x86_64")
440+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
441+
set(SWIFT_HOST_VARIANT_ARCH_default "aarch64")
442+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64")
443+
set(SWIFT_HOST_VARIANT_ARCH_default "powerpc64")
444+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le")
445+
set(SWIFT_HOST_VARIANT_ARCH_default "powerpc64le")
446+
# FIXME: Only matches v6l/v7l - by far the most common variants
447+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l")
448+
set(SWIFT_HOST_VARIANT_ARCH_default "armv6")
449+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l")
450+
set(SWIFT_HOST_VARIANT_ARCH_default "armv7")
451+
else()
452+
message(FATAL_ERROR "Unrecognized architecture on host system: ${CMAKE_SYSTEM_PROCESSOR}")
453+
endif()
454+
endif()
455+
456+
set(SWIFT_HOST_VARIANT_SDK "${SWIFT_HOST_VARIANT_SDK_default}" CACHE STRING
457+
"Deployment sdk for Swift host tools (the compiler).")
458+
set(SWIFT_HOST_VARIANT_ARCH "${SWIFT_HOST_VARIANT_ARCH_default}" CACHE STRING
459+
"Deployment arch for Swift host tools (the compiler).")
460+
412461
#
413462
# Enable additional warnings.
414463
#
@@ -435,114 +484,95 @@ function(is_sdk_requested name result_var_name)
435484
endif()
436485
endfunction()
437486

438-
# FIXME: separate the notions of SDKs used for compiler tools and target
439-
# binaries.
440-
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
487+
# FIXME: the parameters we specify in SWIFT_SDKS are lacking architecture specifics,
488+
# so we need to hard-code it. For example, the SDK for Android is just 'ANDROID',
489+
# which we assume below to be armv7.
490+
# The iOS SDKs all have their architectures hardcoded because they are just specified by name (e.g. 'IOS' or 'WATCHOS').
491+
# We can't cross-compile the standard library for another linux architecture,
492+
# because the SDK list would just be 'LINUX' and we couldn't disambiguate it from the host.
493+
#
494+
# To fix it, we would need to append the architecture to the SDKs,
495+
# for example: 'OSX-x86_64;IOS-armv7;...etc'.
496+
# We could easily do that - we have all of that information in build-script-impl.
497+
# Also, we would need to be provided with the sysroot for each SDK (see SWIFT_ANDROID_SDK_PATH/SWIFT_SDK_ANDROID_PATH).
498+
# Darwin targets cheat and use `xcrun`.
499+
500+
if("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX")
501+
441502
set(CMAKE_EXECUTABLE_FORMAT "ELF")
442-
443503
set(SWIFT_HOST_VARIANT "linux" CACHE STRING
444504
"Deployment OS for Swift host tools (the compiler) [linux].")
445505

446-
set(SWIFT_HOST_VARIANT_SDK "LINUX")
447-
set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX")
448-
449-
# FIXME: This will not work while trying to cross-compile.
450-
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
451-
set(SWIFT_HOST_VARIANT_ARCH "x86_64")
452-
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
453-
454-
if("${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
455-
set(swift_can_crosscompile_stdlib FALSE)
506+
# Calculate the host triple
507+
if("${SWIFT_HOST_TRIPLE}" STREQUAL "")
508+
if("${SWIFT_HOST_VARIANT_ARCH}" STREQUAL "x86_64")
509+
set(SWIFT_HOST_TRIPLE "x86_64-unknown-linux-gnu")
510+
elseif("${SWIFT_HOST_VARIANT_ARCH}" STREQUAL "aarch64")
511+
set(SWIFT_HOST_TRIPLE "aarch64-unknown-linux-gnu")
512+
elseif("${SWIFT_HOST_VARIANT_ARCH}" MATCHES "(powerpc64|powerpc64le)")
513+
set(SWIFT_HOST_TRIPLE "${SWIFT_HOST_VARIANT_ARCH}-unknown-linux-gnu")
514+
elseif("${SWIFT_HOST_VARIANT_ARCH}" MATCHES "(armv6|armv7)")
515+
set(SWIFT_HOST_TRIPLE "${SWIFT_HOST_VARIANT_ARCH}-unknown-linux-gnueabihf")
456516
else()
457-
set(swift_can_crosscompile_stdlib TRUE)
517+
message(FATAL_ERROR "Unable to calculate triple for linux host on ${SWIFT_HOST_VARIANT_ARCH}")
458518
endif()
519+
endif()
459520

460-
is_sdk_requested(LINUX swift_build_linux)
461-
if(swift_build_linux)
462-
configure_sdk_unix(LINUX "Linux" "linux" "linux" "x86_64" "x86_64-unknown-linux-gnu")
463-
set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX")
464-
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
465-
endif()
521+
# Should we build the standard library for the host?
522+
is_sdk_requested(LINUX swift_build_linux)
523+
if(swift_build_linux)
524+
configure_sdk_unix(LINUX "Linux" "linux" "${SWIFT_HOST_VARIANT}" "${SWIFT_HOST_VARIANT_ARCH}" "${SWIFT_HOST_TRIPLE}" "/")
525+
set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}")
526+
set(SWIFT_PRIMARY_VARIANT_ARCH_default "${SWIFT_HOST_VARIANT_ARCH}")
527+
endif()
466528

467-
is_sdk_requested(ANDROID swift_build_android)
468-
if(swift_build_android AND ${swift_can_crosscompile_stdlib})
469-
configure_sdk_unix(ANDROID "Android" "android" "android" "armv7" "armv7-none-linux-androideabi")
470-
# This must be set, as variables such as "${SWIFT_SDK_${sdk}_PATH}" are
471-
# referenced in several other locations.
472-
set(SWIFT_SDK_ANDROID_PATH "${SWIFT_ANDROID_SDK_PATH}")
529+
# Compatible cross-compile SDKS for LINUX: ANDROID (arch always armv7)
530+
is_sdk_requested(ANDROID swift_build_android)
531+
if("${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
532+
set(swift_can_crosscompile_stdlib_android FALSE)
533+
else()
534+
set(swift_can_crosscompile_stdlib_android TRUE)
535+
endif()
473536

537+
if(swift_build_android AND ${swift_can_crosscompile_stdlib_android})
538+
configure_sdk_unix(ANDROID "Android" "android" "android" "armv7" "armv7-none-linux-androideabi" "${SWIFT_ANDROID_SDK_PATH}")
539+
# If we're not building for the host, the cross-compiled target should be the 'primary variant'.
540+
if("${swift_build_linux}" STREQUAL "FALSE")
474541
set(SWIFT_PRIMARY_VARIANT_SDK_default "ANDROID")
475542
set(SWIFT_PRIMARY_VARIANT_ARCH_default "armv7")
476543
endif()
477-
478-
# FIXME: This only matches ARMv6l (by far the most common variant).
479-
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l")
480-
configure_sdk_unix(LINUX "Linux" "linux" "linux" "armv6" "armv6-unknown-linux-gnueabihf")
481-
set(SWIFT_HOST_VARIANT_ARCH "armv6")
482-
set(SWIFT_PRIMARY_VARIANT_ARCH_default "armv6")
483-
# FIXME: This only matches ARMv7l (by far the most common variant).
484-
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l")
485-
configure_sdk_unix(LINUX "Linux" "linux" "linux" "armv7" "armv7-unknown-linux-gnueabihf")
486-
set(SWIFT_HOST_VARIANT_ARCH "armv7")
487-
set(SWIFT_PRIMARY_VARIANT_ARCH_default "armv7")
488-
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
489-
configure_sdk_unix(LINUX "Linux" "linux" "linux" "aarch64" "aarch64-unknown-linux-gnu")
490-
set(SWIFT_HOST_VARIANT_ARCH "aarch64")
491-
set(SWIFT_PRIMARY_VARIANT_ARCH_default "aarch64")
492-
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64")
493-
configure_sdk_unix(LINUX "Linux" "linux" "linux" "powerpc64" "powerpc64-unknown-linux-gnu")
494-
set(SWIFT_HOST_VARIANT_ARCH "powerpc64")
495-
set(SWIFT_PRIMARY_VARIANT_ARCH_default "powerpc64")
496-
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le")
497-
configure_sdk_unix(LINUX "Linux" "linux" "linux" "powerpc64le" "powerpc64le-unknown-linux-gnu")
498-
set(SWIFT_HOST_VARIANT_ARCH "powerpc64le")
499-
set(SWIFT_PRIMARY_VARIANT_ARCH_default "powerpc64le")
500-
else()
501-
message(FATAL_ERROR "Unknown or unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}")
502544
endif()
503545

504-
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
546+
elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "FREEBSD")
547+
548+
set(CMAKE_EXECUTABLE_FORMAT "ELF")
549+
set(SWIFT_HOST_VARIANT "freebsd" CACHE STRING
550+
"Deployment OS for Swift host tools (the compiler) [freebsd].")
551+
505552
# FIXME: Using the host OS version won't produce correct results for
506553
# cross-compilation.
507554
string(REPLACE "[-].*" "" FREEBSD_SYSTEM_VERSION ${CMAKE_SYSTEM_VERSION})
508555
message(STATUS "FreeBSD Version: ${FREEBSD_SYSTEM_VERSION}")
509556
configure_sdk_unix(FREEBSD "FreeBSD" "freebsd" "freebsd" "x86_64"
510-
"x86_64-unknown-freebsd${FREEBSD_SYSTEM_VERSION}")
511-
512-
set(CMAKE_EXECUTABLE_FORMAT "ELF")
513-
514-
set(SWIFT_HOST_VARIANT "freebsd" CACHE STRING
515-
"Deployment OS for Swift host tools (the compiler) [freebsd].")
516-
517-
set(SWIFT_HOST_VARIANT_SDK "FREEBSD")
518-
set(SWIFT_HOST_VARIANT_ARCH "x86_64")
519-
520-
set(SWIFT_PRIMARY_VARIANT_SDK_default "FREEBSD")
557+
"x86_64-unknown-freebsd${FREEBSD_SYSTEM_VERSION}" "/")
558+
set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}")
521559
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
522-
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
523-
configure_sdk_unix(CYGWIN "Cygwin" "windows" "cygwin" "x86_64" "x86_64-unknown-windows-cygnus")
524-
525-
# set(CMAKE_EXECUTABLE_FORMAT "ELF")
526-
560+
561+
elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "CYGWIN")
562+
563+
# set(CMAKE_EXECUTABLE_FORMAT "ELF")
527564
set(SWIFT_HOST_VARIANT "windows" CACHE STRING
528565
"Deployment OS for Swift host tools (the compiler) [windows].")
529-
530-
set(SWIFT_HOST_VARIANT_SDK "CYGWIN")
531-
set(SWIFT_HOST_VARIANT_ARCH "x86_64")
532566

533-
set(SWIFT_PRIMARY_VARIANT_SDK_default "CYGWIN")
567+
configure_sdk_unix(CYGWIN "Cygwin" "windows" "cygwin" "windows" "x86_64-unknown-windows-cygnus" "/")
568+
set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}")
534569
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
535-
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
536-
# Set defaults.
570+
571+
elseif("${SWIFT_HOST_VARIANT_SDK}" MATCHES "(OSX|IOS*|TVOS*|WATCHOS*)")
537572

538573
set(SWIFT_HOST_VARIANT "macosx" CACHE STRING
539574
"Deployment OS for Swift host tools (the compiler) [macosx, iphoneos].")
540575

541-
set(SWIFT_HOST_VARIANT_SDK "OSX" CACHE STRING
542-
"Deployment sdk for Swift host tools (the compiler).")
543-
set(SWIFT_HOST_VARIANT_ARCH "x86_64" CACHE STRING
544-
"Deployment arch for Swift host tools (the compiler).")
545-
546576
# Display Xcode toolchain version.
547577
# The SDK configuration below prints each SDK version.
548578
execute_process(
@@ -563,6 +593,9 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
563593
configure_target_variant(OSX-R "OS X Release" OSX R "Release")
564594
endif()
565595

596+
# Compatible cross-compile SDKS for Darwin OSes: IOS, IOS_SIMULATOR, TVOS,
597+
# TVOS_SIMULATOR, WATCHOS, WATCHOS_SIMULATOR (archs hardcoded below).
598+
566599
if(XCODE)
567600
# FIXME: Cannot cross-compile stdlib using Xcode. Xcode insists on
568601
# passing -mmacosx-version-min to the compiler, and we want to pass
@@ -650,9 +683,10 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
650683
# set(SWIFT_PRIMARY_VARIANT ${SWIFT_PRIMARY_VARIANT_GUESS} CACHE STRING
651684
# "[OSX-DA, OSX-RA, OSX-R, IOS-DA, IOS-RA, IOS-R, IOS_SIMULATOR-DA, IOS_SIMULATOR-RA, IOS_SIMULATOR-R]")
652685
#
653-
# FIXME: hardcode OS X as the default variant for now.
686+
# Primary variant is always OSX; even on iOS hosts.
654687
set(SWIFT_PRIMARY_VARIANT_SDK_default "OSX")
655688
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64")
689+
656690
endif()
657691

658692
if("${SWIFT_PRIMARY_VARIANT_SDK}" STREQUAL "")

cmake/modules/SwiftConfigureSDK.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ macro(configure_sdk_darwin
109109
endmacro()
110110

111111
macro(configure_sdk_unix
112-
prefix name lib_subdir triple_name arch triple)
112+
prefix name lib_subdir triple_name arch triple sdkpath)
113113
# Note: this has to be implemented as a macro because it sets global
114114
# variables.
115115

116116
set(SWIFT_SDK_${prefix}_NAME "${name}")
117-
set(SWIFT_SDK_${prefix}_PATH "/")
117+
set(SWIFT_SDK_${prefix}_PATH "${sdkpath}")
118118
set(SWIFT_SDK_${prefix}_VERSION "don't use")
119119
set(SWIFT_SDK_${prefix}_BUILD_NUMBER "don't use")
120120
set(SWIFT_SDK_${prefix}_DEPLOYMENT_VERSION "don't use")

0 commit comments

Comments
 (0)