Skip to content

Add basic support for Alpine Linux on aarch64 #62245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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].")
Expand All @@ -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
Expand Down Expand Up @@ -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.")
Expand Down
4 changes: 4 additions & 0 deletions cmake/modules/SwiftConfigureSDK.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
Expand Down
33 changes: 18 additions & 15 deletions include/swift/Threading/Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(<threads.h>)
#define SWIFT_THREADING_C11 1
#define SWIFT_THREADING_C11
#elif __has_include(<pthread.h>)
#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.
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Threading/Impl/Linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
27 changes: 27 additions & 0 deletions include/swift/Threading/Impl/Musl.h
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions include/swift/Threading/Impl/Pthreads.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Threading/Mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions utils/build-script-impl
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions utils/swift_build_support/swift_build_support/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -294,6 +299,7 @@ class StdlibDeploymentTarget(object):
AppleTV, AppleTVSimulator,
AppleWatch, AppleWatchSimulator,
Freestanding,
Alpine,
Linux,
FreeBSD,
OpenBSD,
Expand Down