diff --git a/CMakeLists.txt b/CMakeLists.txt index 2eac2ad2734e3..fe23ef2a9a94b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -886,7 +886,7 @@ endif() # We could easily do that - we have all of that information in build-script-impl. # Darwin targets cheat and use `xcrun`. -if("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX") +if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX") OR ("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "ALPINE")) set(SWIFT_HOST_VARIANT "linux" CACHE STRING "Deployment OS for Swift host tools (the compiler) [linux].") @@ -899,6 +899,13 @@ if("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX") set(SWIFT_PRIMARY_VARIANT_ARCH_default "${SWIFT_HOST_VARIANT_ARCH}") endif() + is_sdk_requested(ALPINE swift_build_alpine) + if(swift_build_alpine) + configure_sdk_unix("Alpine" "${SWIFT_HOST_VARIANT_ARCH}") + set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}") + set(SWIFT_PRIMARY_VARIANT_ARCH_default "${SWIFT_HOST_VARIANT_ARCH}") + endif() + is_sdk_requested(FREESTANDING swift_build_freestanding) if(swift_build_freestanding AND (SWIFT_FREESTANDING_FLAVOR STREQUAL "linux")) # TODO @@ -1045,6 +1052,10 @@ endif() list_subtract("${SWIFT_SDKS}" "${SWIFT_CONFIGURED_SDKS}" unknown_sdks) +message(STATUS "SWIFT_HOST_VARIANT_SDK is ${SWIFT_HOST_VARIANT_SDK}") +message(STATUS "SDKs is: ${SWIFT_SDKS}") +message(STATUS "Configured SDKs is: ${SWIFT_CONFIGURED_SDKS}") + precondition(unknown_sdks NEGATE MESSAGE "Unknown SDKs: ${unknown_sdks}") precondition(SWIFT_CONFIGURED_SDKS MESSAGE "No SDKs selected.") precondition(SWIFT_HOST_VARIANT_SDK MESSAGE "No SDK for host tools.") diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake index fbcea50955225..2b86b5d9e407c 100644 --- a/cmake/modules/SwiftConfigureSDK.cmake +++ b/cmake/modules/SwiftConfigureSDK.cmake @@ -320,6 +320,8 @@ macro(configure_sdk_unix name architectures) set(_default_threading_package "pthreads") if("${prefix}" STREQUAL "LINUX") set(_default_threading_package "linux") + elseif("${prefix}" STREQUAL "ALPINE") + set(_default_threading_package "musl") elseif("${prefix}" STREQUAL "WASI") set(_default_threading_package "none") endif() @@ -411,6 +413,8 @@ macro(configure_sdk_unix name architectures) endif() set(SWIFT_SDK_WASI_ARCH_wasm32_PATH "${SWIFT_WASI_SYSROOT_PATH}") set(SWIFT_SDK_WASI_ARCH_wasm32_TRIPLE "wasm32-unknown-wasi") + elseif("${prefix}" STREQUAL "ALPINE") + set(SWIFT_SDK_ALPINE_ARCH_${arch}_TRIPLE "${arch}-alpine-linux-musl") else() message(FATAL_ERROR "unknown Unix OS: ${prefix}") endif() diff --git a/include/swift/Threading/Impl.h b/include/swift/Threading/Impl.h index f734a310b5928..ed90c3e5e4bbb 100644 --- a/include/swift/Threading/Impl.h +++ b/include/swift/Threading/Impl.h @@ -33,37 +33,40 @@ struct stack_bounds { // Try to autodetect if we aren't told what to do -#if !SWIFT_THREADING_NONE && !SWIFT_THREADING_DARWIN && \ - !SWIFT_THREADING_LINUX && !SWIFT_THREADING_PTHREADS && \ - !SWIFT_THREADING_C11 && !SWIFT_THREADING_WIN32 +#if !defined(SWIFT_THREADING_NONE) && !defined(SWIFT_THREADING_DARWIN) && \ + !defined(SWIFT_THREADING_LINUX) && !defined(SWIFT_THREADING_PTHREADS) && \ + !defined(SWIFT_THREADING_C11) && !defined(SWIFT_THREADING_WIN32) && \ + !defined(SWIFT_THREADING_MUSL) #ifdef __APPLE__ -#define SWIFT_THREADING_DARWIN 1 +#define SWIFT_THREADING_DARWIN #elif defined(__linux__) -#define SWIFT_THREADING_LINUX 1 +#define SWIFT_THREADING_LINUX #elif defined(_WIN32) -#define SWIFT_THREADING_WIN32 1 +#define SWIFT_THREADING_WIN32 #elif defined(__wasi__) -#define SWIFT_THREADING_NONE 1 +#define SWIFT_THREADING_NONE #elif __has_include() -#define SWIFT_THREADING_C11 1 +#define SWIFT_THREADING_C11 #elif __has_include() -#define SWIFT_THREADING_PTHREADS 1 +#define SWIFT_THREADING_PTHREADS #else #error Unable to autodetect threading package. Please define SWIFT_THREADING_x as appropriate for your platform. #endif #endif -#if SWIFT_THREADING_NONE +#if defined(SWIFT_THREADING_NONE) #include "Impl/Nothreads.h" -#elif SWIFT_THREADING_DARWIN +#elif defined(SWIFT_THREADING_DARWIN) #include "Impl/Darwin.h" -#elif SWIFT_THREADING_LINUX +#elif defined(SWIFT_THREADING_LINUX) #include "Impl/Linux.h" -#elif SWIFT_THREADING_PTHREADS +#elif defined(SWIFT_THREADING_PTHREADS) #include "Impl/Pthreads.h" -#elif SWIFT_THREADING_C11 +#elif defined(SWIFT_THREADING_MUSL) +#include "Impl/Musl.h" +#elif defined(SWIFT_THREADING_C11) #include "Impl/C11.h" -#elif SWIFT_THREADING_WIN32 +#elif defined(SWIFT_THREADING_WIN32) #include "Impl/Win32.h" #else #error You need to implement Threading/Impl.h for your threading package. diff --git a/include/swift/Threading/Impl/Linux.h b/include/swift/Threading/Impl/Linux.h index 49ce4e811736b..17ff68f85dd6c 100644 --- a/include/swift/Threading/Impl/Linux.h +++ b/include/swift/Threading/Impl/Linux.h @@ -227,4 +227,4 @@ inline void tls_set(tls_key_t key, void *value) { } // namespace swift -#endif // SWIFT_THREADING_IMPL_PTHREADS_H +#endif // SWIFT_THREADING_IMPL_LINUX_H diff --git a/include/swift/Threading/Impl/Musl.h b/include/swift/Threading/Impl/Musl.h new file mode 100644 index 0000000000000..190a14fbb01e0 --- /dev/null +++ b/include/swift/Threading/Impl/Musl.h @@ -0,0 +1,27 @@ +//==-- Musl.h - Threading abstraction implementation for Musl -- -*-C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Implements threading support for plain pthreads, adjusting for Musl. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_THREADING_IMPL_MUSL_H +#define SWIFT_THREADING_IMPL_MUSL_H + +// `PTHREAD_MUTEX_INITIALIZER` can't be made `constexpr` with Musl, working +// around that with these macro directives. +#undef SWIFT_LAZY_MUTEX_INITIALIZER +#define SWIFT_LAZY_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +#include "Pthreads.h" + +#endif // SWIFT_THREADING_IMPL_MUSL_H diff --git a/include/swift/Threading/Impl/Pthreads.h b/include/swift/Threading/Impl/Pthreads.h index 13ef02bb5ef39..fc716c3f966ff 100644 --- a/include/swift/Threading/Impl/Pthreads.h +++ b/include/swift/Threading/Impl/Pthreads.h @@ -29,6 +29,10 @@ #include "swift/Threading/Errors.h" +#ifndef SWIFT_LAZY_MUTEX_INITIALIZER +#define SWIFT_LAZY_MUTEX_INITIALIZER threading_impl::lazy_mutex_initializer() +#endif + namespace swift { namespace threading_impl { @@ -105,11 +109,14 @@ inline void mutex_unsafe_unlock(mutex_handle &handle) { using lazy_mutex_handle = ::pthread_mutex_t; +#if !defined(SWIFT_THREADING_MUSL) // We don't actually need to be lazy here because pthreads has // PTHREAD_MUTEX_INITIALIZER. inline constexpr lazy_mutex_handle lazy_mutex_initializer() { return PTHREAD_MUTEX_INITIALIZER; } +#endif + inline void lazy_mutex_destroy(lazy_mutex_handle &handle) { SWIFT_PTHREADS_CHECK(::pthread_mutex_destroy(&handle)); } diff --git a/include/swift/Threading/Mutex.h b/include/swift/Threading/Mutex.h index 126694c8284f7..cc9601e8867b5 100644 --- a/include/swift/Threading/Mutex.h +++ b/include/swift/Threading/Mutex.h @@ -144,7 +144,7 @@ class LazyMutex { LazyMutex &operator=(LazyMutex &&) = delete; public: - constexpr LazyMutex() : Handle(threading_impl::lazy_mutex_initializer()) {} + constexpr LazyMutex() : Handle(SWIFT_LAZY_MUTEX_INITIALIZER) {} // No destructor; this is intentional; this class is for STATIC allocation // and you don't need to delete mutexes on termination. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 03175207e5cf6..4d29af507047d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -108,6 +108,7 @@ function(get_test_dependencies SDK result_var_name) ("${SDK}" STREQUAL "TVOS_SIMULATOR") OR ("${SDK}" STREQUAL "WATCHOS_SIMULATOR") OR ("${SDK}" STREQUAL "FREESTANDING") OR + ("${SDK}" STREQUAL "ALPINE") OR ("${SDK}" STREQUAL "LINUX") OR ("${SDK}" STREQUAL "CYGWIN") OR ("${SDK}" STREQUAL "FREEBSD") OR diff --git a/utils/build-script-impl b/utils/build-script-impl index 42578d9074f6a..42a2667eb66c4 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -455,6 +455,7 @@ function verify_host_is_supported() { | openbsd-amd64 \ | cygwin-x86_64 \ | haiku-x86_64 \ + | alpine-aarch64 \ | linux-x86_64 \ | linux-i686 \ | linux-armv5 \ diff --git a/utils/swift_build_support/swift_build_support/products/cmake_product.py b/utils/swift_build_support/swift_build_support/products/cmake_product.py index 543facde0f001..10700002cfb81 100644 --- a/utils/swift_build_support/swift_build_support/products/cmake_product.py +++ b/utils/swift_build_support/swift_build_support/products/cmake_product.py @@ -184,6 +184,10 @@ def host_cmake_options(self, host_target): swift_host_triple = 'armv7-unknown-linux-gnueabihf' llvm_target_arch = 'ARM' + elif host_target == 'alpine-aarch64': + swift_host_triple = 'aarch64-alpine-linux-musl' + llvm_target_arch = 'ARM' + elif host_target.startswith('macosx') or \ host_target.startswith('iphone') or \ host_target.startswith('appletv') or \ diff --git a/utils/swift_build_support/swift_build_support/products/product.py b/utils/swift_build_support/swift_build_support/products/product.py index 06f8b6e44ff9a..8085fec069819 100644 --- a/utils/swift_build_support/swift_build_support/products/product.py +++ b/utils/swift_build_support/swift_build_support/products/product.py @@ -332,7 +332,7 @@ def generate_darwin_toolchain_file(self, platform, arch): return toolchain_file - def get_linux_abi(self, arch): + def get_linux_target_components(self, arch): # Map tuples of (platform, arch) to ABI # # E.x.: Hard ABI or Soft ABI for Linux map to gnueabihf @@ -341,22 +341,37 @@ def get_linux_abi(self, arch): 'armv7': ('arm', 'gnueabihf') } - # Default is just arch, gnu - sysroot_arch, abi = arch_platform_to_abi.get(arch, (arch, 'gnu')) - return sysroot_arch, abi + abi = 'gnu' + vendor = 'unknown' + + try: + output = shell.capture(["clang", "--version"]) + + # clang can't handle default `*-unknown-linux-*` components on Alpine, + # it needs special handling to propagate `vendor` and `abi` intact + if 'alpine-linux-musl' in output: + vendor = 'alpine' + abi = 'musl' + + sysroot_arch, abi = arch_platform_to_abi.get(arch, (arch, abi)) + + except BaseException: + # Default is just arch, gnu + sysroot_arch, abi = arch_platform_to_abi.get(arch, (arch, abi)) + return sysroot_arch, vendor, abi def get_linux_sysroot(self, platform, arch): if not self.is_cross_compile_target('{}-{}'.format(platform, arch)): return None - sysroot_arch, abi = self.get_linux_abi(arch) + sysroot_arch, abi = self.get_linux_target_components(arch) # $ARCH-$PLATFORM-$ABI # E.x.: aarch64-linux-gnu sysroot_dirname = '{}-{}-{}'.format(sysroot_arch, platform, abi) return os.path.join(os.sep, 'usr', sysroot_dirname) def get_linux_target(self, platform, arch): - sysroot_arch, abi = self.get_linux_abi(arch) - return '{}-unknown-linux-{}'.format(sysroot_arch, abi) + sysroot_arch, vendor, abi = self.get_linux_target_components(arch) + return '{}-{}-linux-{}'.format(sysroot_arch, vendor, abi) def generate_linux_toolchain_file(self, platform, arch): shell.makedirs(self.build_dir) diff --git a/utils/swift_build_support/swift_build_support/targets.py b/utils/swift_build_support/swift_build_support/targets.py index fec3c432526df..406e090cbcbd3 100644 --- a/utils/swift_build_support/swift_build_support/targets.py +++ b/utils/swift_build_support/swift_build_support/targets.py @@ -260,6 +260,11 @@ class StdlibDeploymentTarget(object): Freestanding = Platform("freestanding", archs=["i386", "x86_64", "armv7", "armv7s", "armv7k", "arm64", "arm64e"]) + + Alpine = Platform("alpine", sdk_name='ALPINE', archs=[ + "x86_64", + "i686", + "aarch64"]) Linux = Platform("linux", archs=[ "x86_64", @@ -294,6 +299,7 @@ class StdlibDeploymentTarget(object): AppleTV, AppleTVSimulator, AppleWatch, AppleWatchSimulator, Freestanding, + Alpine, Linux, FreeBSD, OpenBSD,