swift: add script for on-device build (#4895)

%ci:no-build
This commit is contained in:
buttaface 2020-02-17 17:16:04 +05:30 committed by GitHub
parent 5ec35d6b8e
commit 6d7d47b267
19 changed files with 1730 additions and 0 deletions

100
packages/swift/build.sh Normal file
View File

@ -0,0 +1,100 @@
TERMUX_PKG_HOMEPAGE=https://www.swift.org/
TERMUX_PKG_DESCRIPTION="Swift is a high-performance system programming language"
TERMUX_PKG_LICENSE="Apache-2.0, NCSA"
TERMUX_PKG_VERSION=5.1.4
TERMUX_PKG_SHA256=46765a6a604be0b11cb4660bf5adbef8a95d2b74b03aa46860ef81a5ba92d5e8
TERMUX_PKG_SRCURL=https://github.com/apple/swift/archive/swift-$TERMUX_PKG_VERSION-RELEASE.tar.gz
TERMUX_PKG_DEPENDS="binutils-gold, libc++, ndk-sysroot, libandroid-spawn, libcurl, libicu, libsqlite, libuuid, libxml2, llbuild"
TERMUX_PKG_BLACKLISTED_ARCHES="arm, i686, x86_64"
TERMUX_PKG_NO_STATICSPLIT=true
SWIFT_BUILD_PACKAGES="cmake, ninja, perl, pkg-config, python2, rsync"
SWIFT_COMPONENTS="autolink-driver;compiler;clang-builtin-headers;stdlib;swift-remote-mirror;sdk-overlay;parser-lib;toolchain-tools;license;sourcekit-inproc"
SWIFT_BUILD_FLAGS="-R --no-assertions --llvm-targets-to-build='X86;ARM;AArch64'
--xctest -b -p -j $TERMUX_MAKE_PROCESSES --build-subdir=. --install-destdir=/
--install-prefix=$TERMUX_PREFIX --swift-install-components='$SWIFT_COMPONENTS'"
termux_step_post_extract_package() {
if [ "$TERMUX_ON_DEVICE_BUILD" = "false" ]; then
termux_error_exit "Package '$TERMUX_PKG_NAME' is not ready for off-device builds."
else
echo "Stop and install these required build packages if you haven't already:"
printf "$SWIFT_BUILD_PACKAGES\n\n"
fi
# The Swift build-script requires a particular organization of source directories,
# which the following sets up.
mkdir TEMP
mv [a-zA-S]* TEMP/
mv TEMP swift
declare -A library_checksums
library_checksums[swift-cmark]=dc02253fdc5ef4027551e5ab5cb8eef22abd7a5bb2df6a2baf02e17afdeeb5cd
library_checksums[llvm-project]=0b3606be7b542aff28210c96639ad19a4b982e999fb3e86748198d8150f5f3d3
library_checksums[swift-corelibs-libdispatch]=079cff5dd5b05381e9cf3094d445652fa9990a7d3a46e122f1e1dcdb2c54ddc1
library_checksums[swift-corelibs-foundation]=f6e09efb3998d0a3d449f92ea809c86346c66e3b2d83ed19f3335bcb29401416
library_checksums[swift-corelibs-xctest]=5996eb4384c8f095d912424439c5a1b7fc9ff57529f9ac5ecbc04e82d22ebca2
library_checksums[swift-llbuild]=537683d7f1a73b48017d7cd7cd587c4b75c55cc5584e206cc0f8f92f6f4dd3ea
library_checksums[swift-package-manager]=b421e7e171b94521e364b6ea21ddd6300fe28bce3a0fcbc9f5ed6db496f148a6
for library in "${!library_checksums[@]}"; do \
termux_download \
https://github.com/apple/$library/archive/swift-$TERMUX_PKG_VERSION-RELEASE.tar.gz \
$TERMUX_PKG_CACHEDIR/$library-$TERMUX_PKG_VERSION.tar.gz \
${library_checksums[$library]}
tar xf $TERMUX_PKG_CACHEDIR/$library-$TERMUX_PKG_VERSION.tar.gz
mv $library-swift-${TERMUX_PKG_VERSION}-RELEASE $library
done
mv swift-cmark cmark
ln -s $PWD/llvm-project/llvm
ln -s $PWD/llvm-project/compiler-rt
ln -s $PWD/llvm-project/clang
mv swift-llbuild llbuild
mv swift-package-manager swiftpm
}
termux_step_pre_configure() {
cd llbuild
# The bare minimum patches needed from the existing llbuild package
patch -p1 < $TERMUX_PKG_BUILDER_DIR/../llbuild/CMakeLists.txt.patch
patch -p1 < $TERMUX_PKG_BUILDER_DIR/../llbuild/include-llvm-Config-config.h.patch
patch -p1 < $TERMUX_PKG_BUILDER_DIR/../llbuild/lib-llvm-Support-CmakeLists.txt.patch
}
termux_step_configure() {
if [ "$(dpkg-query -W -f '${db:Status-Status}\n' libdispatch 2>/dev/null)" == "installed" ]; then
echo "This script will overwrite shared libraries provided by the libdispatch package."
echo "Uninstall libdispatch first with 'pkg uninstall libdispatch'."
termux_error_exit "Package '$TERMUX_PKG_NAME' overwrites 'libdispatch', so uninstall it."
fi
local PYTHON2_PATH=$(which python2)
if [ -z "$PYTHON2_PATH" ]; then
echo "Python 2 couldn't be found. Install these required build packages first:"
echo "$SWIFT_BUILD_PACKAGES"
termux_error_exit "Package '$TERMUX_PKG_NAME' requires Python 2 to build."
else
ln -s $PYTHON2_PATH python
export PATH=$TERMUX_PKG_BUILDDIR:$PATH
fi
}
termux_step_make() {
SWIFT_BUILD_ROOT=$TERMUX_PKG_BUILDDIR $TERMUX_PKG_SRCDIR/swift/utils/build-script \
$SWIFT_BUILD_FLAGS
}
termux_step_make_install() {
SWIFT_BUILD_ROOT=$TERMUX_PKG_BUILDDIR $TERMUX_PKG_SRCDIR/swift/utils/build-script \
$SWIFT_BUILD_FLAGS --install-swift --install-libdispatch --install-foundation \
--install-xctest --install-swiftpm --llvm-install-components=IndexStore
# A hack to remove libdispatch libraries installed by the above build-script, which would
# overwrite the libdispatch package if installed.
rm $TERMUX_PREFIX/lib/libdispatch.so $TERMUX_PREFIX/lib/libBlocksRuntime.so
mkdir -p $TERMUX_PREFIX/lib/swift/pm/llbuild
cp llbuild-android-aarch64/lib/libllbuildSwift.so $TERMUX_PREFIX/lib/swift/pm/llbuild
}

View File

@ -0,0 +1,22 @@
diff --git a/llbuild/cmake/modules/Utility.cmake b/llbuild/cmake/modules/Utility.cmake
index b287975..6a1859e 100644
--- a/llbuild/cmake/modules/Utility.cmake
+++ b/llbuild/cmake/modules/Utility.cmake
@@ -208,7 +208,7 @@ function(add_swift_module target name deps sources additional_args)
list(APPEND DYLYB_ARGS -Xlinker -rpath -Xlinker @loader_path)
list(APPEND DYLYB_ARGS -Xlinker -install_name -Xlinker @rpath/${target}.${DYLIB_EXT})
else()
- list(APPEND DYLYB_ARGS -Xlinker "-rpath=\\$$ORIGIN")
+ #list(APPEND DYLYB_ARGS -Xlinker "-rpath=\\$$ORIGIN")
endif()
# Runpath for finding Swift core libraries in the toolchain.
@@ -216,7 +216,7 @@ function(add_swift_module target name deps sources additional_args)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
list(APPEND DYLYB_ARGS -Xlinker -rpath -Xlinker @loader_path/../../macosx)
else()
- list(APPEND DYLYB_ARGS -Xlinker "-rpath=\\$$ORIGIN/../../linux")
+ list(APPEND DYLYB_ARGS -Xlinker "-rpath=\\$$ORIGIN/../../android")
endif()
list(APPEND DYLYB_ARGS -L ${LLBUILD_LIBRARY_OUTPUT_INTDIR})

View File

@ -0,0 +1,13 @@
diff --git a/llbuild/products/llbuildSwift/BuildSystemBindings.swift b/llbuild/products/llbuildSwift/BuildSystemBindings.swift
index 33b3e88..1236069 100644
--- a/llbuild/products/llbuildSwift/BuildSystemBindings.swift
+++ b/llbuild/products/llbuildSwift/BuildSystemBindings.swift
@@ -8,7 +8,7 @@
// This file contains Swift bindings for the llbuild C API.
-#if os(Linux)
+#if canImport(Glibc)
import Glibc
#elseif os(Windows)
import MSVCRT

View File

@ -0,0 +1,11 @@
--- a/llvm-project/clang/lib/Driver/ToolChain.cpp 2016-12-14 17:46:50.000000000 +0100
+++ b/llvm-project/clang/lib/Driver/ToolChain.cpp 2017-07-13 12:35:02.862534376 +0200
@@ -632,7 +632,7 @@
switch (Type) {
case ToolChain::CST_Libcxx:
- CmdArgs.push_back("-lc++");
+ CmdArgs.push_back("-lc++_shared");
break;
case ToolChain::CST_Libstdcxx:

View File

@ -0,0 +1,73 @@
--- a/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp.orig 2019-12-21 22:30:03.676720096 +0000
+++ b/llvm-project/clang/lib/Driver/ToolChains/Linux.cpp 2019-12-21 22:34:42.941719383 +0000
@@ -316,6 +316,41 @@
const std::string OSLibDir = getOSLibDir(Triple, Args);
const std::string MultiarchTriple = getMultiarchTriple(D, Triple, SysRoot);
+ bool NativeBuild = true;
+
+ if(IsAndroid) {
+ if (Triple == llvm::Triple(llvm::sys::getDefaultTargetTriple()))
+ addPathIfExists(D, SysRoot + "@TERMUX_PREFIX@/lib", Paths);
+ else
+ NativeBuild = false;
+
+ if (Arch == llvm::Triple::aarch64) {
+ addPathIfExists(D, SysRoot + "@TERMUX_PREFIX@/aarch64-linux-android/lib", Paths);
+ addPathIfExists(D, SysRoot + "/system/lib64", Paths);
+ if (!NativeBuild)
+ ExtraOpts.push_back("-rpath=@TERMUX_PREFIX@/aarch64-linux-android/lib");
+ }
+ else if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) {
+ addPathIfExists(D, SysRoot + "@TERMUX_PREFIX@/arm-linux-androideabi/lib", Paths);
+ addPathIfExists(D, SysRoot + "/system/lib", Paths);
+ if (!NativeBuild)
+ ExtraOpts.push_back("-rpath=@TERMUX_PREFIX@/arm-linux-androideabi/lib");
+ }
+ else if (Arch == llvm::Triple::x86_64) {
+ addPathIfExists(D, SysRoot + "@TERMUX_PREFIX@/x86_64-linux-android/lib", Paths);
+ addPathIfExists(D, SysRoot + "/system/lib64", Paths);
+ if (!NativeBuild)
+ ExtraOpts.push_back("-rpath=@TERMUX_PREFIX@/x86_64-linux-android/lib");
+ }
+ else if (Arch == llvm::Triple::x86) {
+ addPathIfExists(D, SysRoot + "@TERMUX_PREFIX@/i686-linux-android/lib", Paths);
+ addPathIfExists(D, SysRoot + "/system/lib", Paths);
+ if (!NativeBuild)
+ ExtraOpts.push_back("-rpath=@TERMUX_PREFIX@/i686-linux-android/lib");
+ }
+
+ ExtraOpts.push_back("-rpath=@TERMUX_PREFIX@/lib");
+ }
// Add the multilib suffixed paths where they are available.
if (GCCInstallation.isValid()) {
@@ -656,8 +691,27 @@
return;
if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
+ if (getTriple().isAndroid()) {
+ switch (getTriple().getArch()) {
+ case llvm::Triple::x86_64:
+ addSystemInclude(DriverArgs, CC1Args, SysRoot + "@TERMUX_PREFIX@/include/x86_64-linux-android");
+ break;
+ case llvm::Triple::x86:
+ addSystemInclude(DriverArgs, CC1Args, SysRoot + "@TERMUX_PREFIX@/include/i686-linux-android");
+ break;
+ case llvm::Triple::aarch64:
+ addSystemInclude(DriverArgs, CC1Args, SysRoot + "@TERMUX_PREFIX@/include/aarch64-linux-android");
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ addSystemInclude(DriverArgs, CC1Args, SysRoot + "@TERMUX_PREFIX@/include/arm-linux-androideabi");
+ break;
+ default:
+ break;
+ }
+
addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
-
+ }
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
SmallString<128> P(D.ResourceDir);
llvm::sys::path::append(P, "include");

View File

@ -0,0 +1,13 @@
diff --git a/llvm-project/clang/tools/IndexStore/CMakeLists.txt b/llvm-project/clang/tools/IndexStore/CMakeLists.txt
index 1bcfc0734785..ddb77c91b22d 100644
--- a/llvm-project/clang/tools/IndexStore/CMakeLists.txt
+++ b/llvm-project/clang/tools/IndexStore/CMakeLists.txt
@@ -65,7 +65,7 @@ if (LLVM_INSTALL_TOOLCHAIN_ONLY)
endif()
endif()
-set(INDEXSTORE_HEADERS_INSTALL_DESTINATION "local/include")
+set(INDEXSTORE_HEADERS_INSTALL_DESTINATION "include")
install(DIRECTORY ../../include/indexstore
COMPONENT IndexStore

View File

@ -0,0 +1,95 @@
diff --git a/swift/utils/build-script b/swift/utils/build-script
index 05fd5f6b0f5..06fc0251719 100755
--- a/swift/utils/build-script
+++ b/swift/utils/build-script
@@ -325,7 +325,11 @@ class BuildScriptInvocation(object):
android_tgts = [tgt for tgt in args.stdlib_deployment_targets
if StdlibDeploymentTarget.Android.contains(tgt)]
if not args.android and len(android_tgts) > 0:
- args.android = True
+ # If building natively on an Android host, avoid the NDK
+ # cross-compilation configuration.
+ if not StdlibDeploymentTarget.Android.contains( \
+ StdlibDeploymentTarget.host_target().name):
+ args.android = True
args.build_android = False
# Include the Darwin supported architectures in the CMake options.
@@ -767,6 +771,10 @@ class BuildScriptInvocation(object):
"--android-icu-i18n-include", args.android_icu_i18n_include,
"--android-icu-data", args.android_icu_data,
]
+ # If building natively on an Android host, only pass the API level.
+ if StdlibDeploymentTarget.Android.contains( \
+ StdlibDeploymentTarget.host_target().name):
+ impl_args += ["--android-api-level", args.android_api_level]
if args.android_deploy_device_path:
impl_args += [
"--android-deploy-device-path",
diff --git a/swift/utils/build-script-impl b/swift/utils/build-script-impl
index 68d7f5ddd88..5f6bfc2c57b 100755
--- a/swift/utils/build-script-impl
+++ b/swift/utils/build-script-impl
@@ -449,6 +449,16 @@ function set_build_options_for_host() {
SWIFT_HOST_VARIANT_SDK="HAIKU"
SWIFT_HOST_VARIANT_ARCH="x86_64"
;;
+ android-aarch64)
+ SWIFT_HOST_VARIANT="android"
+ SWIFT_HOST_VARIANT_SDK="ANDROID"
+ SWIFT_HOST_VARIANT_ARCH="aarch64"
+ SWIFT_HOST_TRIPLE="aarch64-unknown-linux-android"
+ llvm_target_arch="AArch64"
+ swift_cmake_options=(
+ -DSWIFT_ANDROID_API_LEVEL:STRING="${ANDROID_API_LEVEL}"
+ )
+ ;;
linux-*)
SWIFT_HOST_VARIANT="linux"
SWIFT_HOST_VARIANT_SDK="LINUX"
@@ -716,6 +726,8 @@
llvm_cmake_options+=(
-DLLVM_TOOL_COMPILER_RT_BUILD:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})"
-DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})"
+ -DC_INCLUDE_DIRS:STRING="@TERMUX_PREFIX@/include"
+ -DCOMPILER_RT_INCLUDE_TESTS:BOOL="OFF"
)
# If we are asked to not generate test targets for LLVM and or Swift,
@@ -2895,7 +2907,7 @@
elif [[ "$(uname -s)" == "Haiku" ]] ; then
HOST_CXX_HEADERS_DIR="/boot/system/develop/headers/c++"
else # Linux
- HOST_CXX_HEADERS_DIR="/usr/include/c++"
+ HOST_CXX_HEADERS_DIR="@TERMUX_PREFIX@/include/c++"
fi
# Find the path in which the local clang build is expecting to find
@@ -3654,7 +3666,7 @@ for host in "${ALL_HOSTS[@]}"; do
fi
case ${host} in
- linux-*|freebsd-*|cygwin-*|haiku-*) ;;
+ linux-*|freebsd-*|cygwin-*|haiku-*|android-*) ;;
*)
echo "error: --install-xctest is not supported on this platform"
exit 1
diff --git a/swift/utils/swift_build_support/swift_build_support/targets.py b/swift/utils/swift_build_support/swift_build_support/targets.py
index 7fae08ca57b..89637be0ee5 100644
--- a/swift/utils/swift_build_support/swift_build_support/targets.py
+++ b/swift/utils/swift_build_support/swift_build_support/targets.py
@@ -159,6 +159,14 @@ class StdlibDeploymentTarget(object):
machine = platform.machine()
if system == 'Linux':
+ if 'ANDROID_DATA' in os.environ:
+ if machine.startswith('armv7'):
+ return StdlibDeploymentTarget.Android.armv7
+ elif machine == 'aarch64':
+ return StdlibDeploymentTarget.Android.aarch64
+ raise NotImplementedError('Android System with architecture "%s"'
+ ' is not supported' % machine)
+
if machine == 'x86_64':
return StdlibDeploymentTarget.Linux.x86_64
elif machine == 'i686':

View File

@ -0,0 +1,343 @@
diff --git a/swift/CMakeLists.txt b/swift/CMakeLists.txt
index 41768247e5..e67bf868ad 100644
--- a/swift/CMakeLists.txt
+++ b/swift/CMakeLists.txt
@@ -439,7 +439,7 @@ precondition(CMAKE_SYSTEM_NAME)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
set(SWIFT_BUILD_SYNTAXPARSERLIB_default TRUE)
set(SWIFT_BUILD_SOURCEKIT_default TRUE)
-elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL Android)
if(EXISTS ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE})
set(SWIFT_BUILD_SYNTAXPARSERLIB_default TRUE)
set(SWIFT_BUILD_SOURCEKIT_default TRUE)
@@ -621,6 +621,8 @@ else()
set(SWIFT_HOST_VARIANT_SDK_default "WINDOWS")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku")
set(SWIFT_HOST_VARIANT_SDK_default "HAIKU")
+ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
+ set(SWIFT_HOST_VARIANT_SDK_default "ANDROID")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
set(SWIFT_HOST_VARIANT_SDK_default "OSX")
else()
@@ -745,6 +747,22 @@ elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "HAIKU")
set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}")
set(SWIFT_PRIMARY_VARIANT_ARCH_default "${SWIFT_HOST_VARIANT_ARCH}")
+elseif("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "ANDROID")
+
+ set(SWIFT_HOST_VARIANT "android" CACHE STRING
+ "Deployment OS for Swift host tools (the compiler) [android]")
+
+ set(SWIFT_ANDROID_NATIVE_SYSROOT "/data/data/com.termux/files" CACHE STRING
+ "Path to Android sysroot, default initialized to the Termux app's layout")
+
+ if("${SWIFT_SDK_ANDROID_ARCHITECTURES}" STREQUAL "")
+ set(SWIFT_SDK_ANDROID_ARCHITECTURES ${SWIFT_HOST_VARIANT_ARCH})
+ endif()
+
+ configure_sdk_unix("Android" "${SWIFT_SDK_ANDROID_ARCHITECTURES}")
+ set(SWIFT_PRIMARY_VARIANT_SDK_default "${SWIFT_HOST_VARIANT_SDK}")
+ set(SWIFT_PRIMARY_VARIANT_ARCH_default "${SWIFT_HOST_VARIANT_ARCH}")
+
elseif("${SWIFT_HOST_VARIANT_SDK}" MATCHES "(OSX|IOS*|TVOS*|WATCHOS*)")
set(SWIFT_HOST_VARIANT "macosx" CACHE STRING
diff --git a/swift/cmake/modules/AddSwift.cmake b/swift/cmake/modules/AddSwift.cmake
index cbf613b4fc..47f926b4b8 100644
--- a/swift/cmake/modules/AddSwift.cmake
+++ b/swift/cmake/modules/AddSwift.cmake
@@ -140,7 +140,8 @@ function(_add_variant_c_compile_link_flags)
# lld can handle targeting the android build. However, if lld is not
# enabled, then fallback to the linker included in the android NDK.
if(NOT SWIFT_ENABLE_LLD_LINKER)
- list(APPEND result "-B" "${SWIFT_SDK_ANDROID_ARCH_${CFLAGS_ARCH}_NDK_PREBUILT_PATH}/${SWIFT_SDK_ANDROID_ARCH_${CFLAGS_ARCH}_NDK_TRIPLE}/bin")
+ swift_android_tools_path(${CFLAGS_ARCH} tools_path)
+ list(APPEND result "-B" "${tools_path}")
endif()
endif()
@@ -434,19 +435,12 @@ function(_add_variant_link_flags)
list(APPEND link_libraries "bsd" "atomic")
list(APPEND result "-Wl,-Bsymbolic")
elseif("${LFLAGS_SDK}" STREQUAL "ANDROID")
- list(APPEND link_libraries "dl" "log" "atomic" "icudataswift" "icui18nswift" "icuucswift")
+ list(APPEND link_libraries "dl" "log" "atomic" "icudata" "icui18n" "icuuc")
# We provide our own C++ below, so we ask the linker not to do it. However,
# we need to add the math library, which is linked implicitly by libc++.
list(APPEND result "-nostdlib++" "-lm")
- if("${LFLAGS_ARCH}" MATCHES armv7)
- set(android_libcxx_path "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a")
- elseif("${LFLAGS_ARCH}" MATCHES aarch64)
- set(android_libcxx_path "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/arm64-v8a")
- else()
- message(SEND_ERROR "unknown architecture (${LFLAGS_ARCH}) for android")
- endif()
- list(APPEND link_libraries "${android_libcxx_path}/libc++abi.a")
- list(APPEND link_libraries "${android_libcxx_path}/libc++_shared.so")
+ swift_android_cxx_libraries_for_arch(${LFLAGS_ARCH} cxx_link_libraries)
+ list(APPEND link_libraries ${cxx_link_libraries})
swift_android_lib_for_arch(${LFLAGS_ARCH} ${LFLAGS_ARCH}_LIB)
foreach(path IN LISTS ${LFLAGS_ARCH}_LIB)
list(APPEND library_search_directories ${path})
@@ -1053,7 +1047,7 @@ function(_add_swift_library_single target name)
set_target_properties("${target}"
PROPERTIES
INSTALL_NAME_DIR "${install_name_dir}")
- elseif("${SWIFTLIB_SINGLE_SDK}" STREQUAL "LINUX" AND NOT "${SWIFTLIB_SINGLE_SDK}" STREQUAL "ANDROID")
+ elseif("${SWIFTLIB_SINGLE_SDK}" STREQUAL "LINUX")
set_target_properties("${target}"
PROPERTIES
INSTALL_RPATH "$ORIGIN:/usr/lib/swift/linux")
@@ -1061,6 +1061,10 @@ function(_add_swift_library_single target name)
set_target_properties("${target}"
PROPERTIES
INSTALL_RPATH "$ORIGIN:/usr/lib/swift/cygwin")
+ elseif("${SWIFTLIB_SINGLE_SDK}" STREQUAL "ANDROID")
+ set_target_properties("${target}"
+ PROPERTIES
+ INSTALL_RPATH "$ORIGIN")
endif()
set_target_properties("${target}" PROPERTIES BUILD_WITH_INSTALL_RPATH YES)
diff --git a/swift/cmake/modules/AddSwiftUnittests.cmake b/swift/cmake/modules/AddSwiftUnittests.cmake
index 52dcbabab5..635253a448 100644
--- a/swift/cmake/modules/AddSwiftUnittests.cmake
+++ b/swift/cmake/modules/AddSwiftUnittests.cmake
@@ -42,9 +42,14 @@ function(add_swift_unittest test_dirname)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
set_property(TARGET "${test_dirname}" APPEND_STRING PROPERTY
LINK_FLAGS " -Xlinker -rpath -Xlinker ${SWIFT_LIBRARY_OUTPUT_INTDIR}/swift/macosx")
+ elseif("${SWIFT_HOST_VARIANT}" STREQUAL "android")
+ swift_android_lib_for_arch(${SWIFT_HOST_VARIANT_ARCH} android_system_libs)
+ set_property(TARGET "${test_dirname}" APPEND PROPERTY LINK_DIRECTORIES
+ "${android_system_libs}")
+ set_property(TARGET "${test_dirname}" APPEND PROPERTY LINK_LIBRARIES "log")
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
- set_property(TARGET "${test_dirname}" APPEND_STRING PROPERTY
- LINK_FLAGS " -latomic")
+ set_property(TARGET "${test_dirname}" APPEND PROPERTY LINK_LIBRARIES
+ "atomic")
endif()
find_program(LDLLD_PATH "ld.lld")
diff --git a/swift/cmake/modules/SwiftAndroidSupport.cmake b/swift/cmake/modules/SwiftAndroidSupport.cmake
index c6dcc783c6..9379031947 100644
--- a/swift/cmake/modules/SwiftAndroidSupport.cmake
+++ b/swift/cmake/modules/SwiftAndroidSupport.cmake
@@ -1,16 +1,32 @@
function(swift_android_libcxx_include_paths var)
- set(${var}
- "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/include"
- "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++abi/include"
- PARENT_SCOPE)
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ set(${var}
+ "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/include"
+ "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++abi/include"
+ PARENT_SCOPE)
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ set(${var}
+ "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/include/c++/v1"
+ PARENT_SCOPE)
+ else()
+ message(SEND_ERROR "Couldn't set libc++ include paths for Android")
+ endif()
endfunction()
function(swift_android_include_for_arch arch var)
set(paths)
- list(APPEND paths
- "${SWIFT_ANDROID_NDK_PATH}/sources/android/support/include"
- "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include"
- "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include/${SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_TRIPLE}")
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ list(APPEND paths
+ "${SWIFT_ANDROID_NDK_PATH}/sources/android/support/include"
+ "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include"
+ "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include/${SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_TRIPLE}")
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ list(APPEND paths
+ "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/include"
+ "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/include/${SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_TRIPLE}")
+ else()
+ message(SEND_ERROR "Couldn't set ${arch} include paths for Android")
+ endif()
set(${var} ${paths} PARENT_SCOPE)
endfunction()
@@ -19,14 +35,68 @@ function(swift_android_lib_for_arch arch var)
set(_host "${SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_TRIPLE}")
set(paths)
- if(arch STREQUAL armv7)
- list(APPEND paths "${_prebuilt}/${_host}/lib/armv7-a")
- elseif(arch STREQUAL aarch64)
- list(APPEND paths "${_prebuilt}/${_host}/lib64")
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ if(arch STREQUAL armv7)
+ list(APPEND paths "${_prebuilt}/${_host}/lib/armv7-a")
+ elseif(arch STREQUAL aarch64)
+ list(APPEND paths "${_prebuilt}/${_host}/lib64")
+ elseif(arch STREQUAL i686)
+ list(APPEND paths "${_prebuilt}/${_host}/lib")
+ elseif(arch STREQUAL x86_64)
+ list(APPEND paths "${_prebuilt}/${_host}/lib64")
+ else()
+ message(SEND_ERROR "unknown architecture (${arch}) for android")
+ endif()
+ list(APPEND paths "${_prebuilt}/lib/gcc/${_host}/${SWIFT_ANDROID_NDK_GCC_VERSION}.x")
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ list(APPEND paths "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/lib")
+ if("${arch}" MATCHES armv7)
+ list(APPEND paths "/system/lib")
+ elseif("${arch}" MATCHES aarch64)
+ list(APPEND paths "/system/lib64")
+ else()
+ message(SEND_ERROR "unknown architecture (${arch}) when compiling for Android host")
+ endif()
else()
- message(SEND_ERROR "unknown architecture (${arch}) for android")
+ message(SEND_ERROR "Couldn't set ${arch} library paths for Android")
endif()
- list(APPEND paths "${_prebuilt}/lib/gcc/${_host}/${SWIFT_ANDROID_NDK_GCC_VERSION}.x")
set(${var} ${paths} PARENT_SCOPE)
endfunction()
+
+function(swift_android_tools_path arch path_var_name)
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ set(${path_var_name} "${SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_PREBUILT_PATH}/${SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_TRIPLE}/bin" PARENT_SCOPE)
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ set(${path_var_name} "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/bin" PARENT_SCOPE)
+ else()
+ message(SEND_ERROR "Couldn't set ${arch} tools path for Android")
+ endif()
+endfunction ()
+
+function(swift_android_cxx_libraries_for_arch arch libraries_var_name)
+ set(link_libraries)
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ if("${arch}" MATCHES armv7)
+ set(cxx_arch armeabi-v7a)
+ elseif("${arch}" MATCHES aarch64)
+ set(cxx_arch arm64-v8a)
+ elseif("${arch}" MATCHES i686)
+ set(cxx_arch x86)
+ elseif("${arch}" MATCHES x86_64)
+ set(cxx_arch x86_64)
+ else()
+ message(SEND_ERROR "unknown architecture (${arch}) when cross-compiling for Android")
+ endif()
+
+ set(android_libcxx_path "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/${cxx_arch}")
+ list(APPEND link_libraries ${android_libcxx_path}/libc++abi.a
+ ${android_libcxx_path}/libc++_shared.so)
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ list(APPEND link_libraries "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/lib/libc++_shared.so")
+ else()
+ message(SEND_ERROR "Couldn't set ${arch} libc++ libraries needed for Android")
+ endif()
+
+ set(${libraries_var_name} ${link_libraries} PARENT_SCOPE)
+endfunction()
diff --git a/swift/cmake/modules/SwiftConfigureSDK.cmake b/swift/cmake/modules/SwiftConfigureSDK.cmake
index cb9c7e9ace..a745aa440f 100644
--- a/swift/cmake/modules/SwiftConfigureSDK.cmake
+++ b/swift/cmake/modules/SwiftConfigureSDK.cmake
@@ -28,7 +28,12 @@ function(_report_sdk prefix)
message(STATUS " ${arch} LIB: ${${arch}_LIB}")
endforeach()
elseif("${prefix}" STREQUAL "ANDROID")
- message(STATUS " NDK Dir: $ENV{SWIFT_ANDROID_NDK_PATH}")
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ message(STATUS " NDK: $ENV{SWIFT_ANDROID_NDK_PATH}")
+ endif()
+ if(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ message(STATUS " Sysroot: ${SWIFT_ANDROID_NATIVE_SYSROOT}")
+ endif()
foreach(arch ${SWIFT_SDK_${prefix}_ARCHITECTURES})
swift_android_include_for_arch(${arch} ${arch}_INCLUDE)
swift_android_lib_for_arch(${arch} ${arch}_LIB)
@@ -203,12 +208,24 @@ macro(configure_sdk_unix name architectures)
if("${arch}" STREQUAL "armv7")
set(SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_TRIPLE "arm-linux-androideabi")
set(SWIFT_SDK_ANDROID_ARCH_${arch}_ALT_SPELLING "arm")
- set(SWIFT_SDK_ANDROID_ARCH_${arch}_PATH "${SWIFT_ANDROID_NDK_PATH}/platforms/android-${SWIFT_ANDROID_API_LEVEL}/arch-arm")
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ set(SWIFT_SDK_ANDROID_ARCH_${arch}_PATH "${SWIFT_ANDROID_NDK_PATH}/platforms/android-${SWIFT_ANDROID_API_LEVEL}/arch-arm")
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ set(SWIFT_SDK_ANDROID_ARCH_${arch}_PATH "${SWIFT_ANDROID_NATIVE_SYSROOT}")
+ else()
+ message(SEND_ERROR "Couldn't find SWIFT_SDK_ANDROID_ARCH_armv7_PATH")
+ endif()
set(SWIFT_SDK_ANDROID_ARCH_${arch}_TRIPLE "armv7-none-linux-androideabi")
elseif("${arch}" STREQUAL "aarch64")
set(SWIFT_SDK_ANDROID_ARCH_${arch}_NDK_TRIPLE "aarch64-linux-android")
set(SWIFT_SDK_ANDROID_ARCH_${arch}_ALT_SPELLING "aarch64")
- set(SWIFT_SDK_ANDROID_ARCH_${arch}_PATH "${SWIFT_ANDROID_NDK_PATH}/platforms/android-${SWIFT_ANDROID_API_LEVEL}/arch-arm64")
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ set(SWIFT_SDK_ANDROID_ARCH_${arch}_PATH "${SWIFT_ANDROID_NDK_PATH}/platforms/android-${SWIFT_ANDROID_API_LEVEL}/arch-arm64")
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ set(SWIFT_SDK_ANDROID_ARCH_${arch}_PATH "${SWIFT_ANDROID_NATIVE_SYSROOT}")
+ else()
+ message(SEND_ERROR "Couldn't find SWIFT_SDK_ANDROID_ARCH_aarch64_PATH")
+ endif()
set(SWIFT_SDK_ANDROID_ARCH_${arch}_TRIPLE "aarch64-unknown-linux-android")
else()
message(FATAL_ERROR "unknown arch for android SDK: ${arch}")
diff --git a/swift/stdlib/public/Platform/CMakeLists.txt b/swift/stdlib/public/Platform/CMakeLists.txt
index daf497b7e9..457743dc25 100644
--- a/swift/stdlib/public/Platform/CMakeLists.txt
+++ b/swift/stdlib/public/Platform/CMakeLists.txt
@@ -63,8 +63,15 @@ foreach(sdk ${SWIFT_SDKS})
set(GLIBC_ARCH_INCLUDE_PATH "/system/develop/headers/posix")
set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "/system/develop/headers/")
elseif("${sdk}" STREQUAL "ANDROID")
- set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include")
- set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include")
+ if(NOT "${SWIFT_ANDROID_NDK_PATH}" STREQUAL "")
+ set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include")
+ set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${SWIFT_ANDROID_NDK_PATH}/sysroot/usr/include")
+ elseif(NOT "${SWIFT_ANDROID_NATIVE_SYSROOT}" STREQUAL "")
+ set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/include")
+ set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${SWIFT_ANDROID_NATIVE_SYSROOT}/usr/include")
+ else()
+ message(SEND_ERROR "Couldn't find GLIBC_SYSROOT_PATH for Android")
+ endif()
else()
# Determine the location of glibc headers based on the target.
set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "/usr/include")
diff --git a/swift/test/CMakeLists.txt b/swift/test/CMakeLists.txt
index 18396dd873..706f59193c 100644
--- a/swift/test/CMakeLists.txt
+++ b/swift/test/CMakeLists.txt
@@ -211,7 +211,9 @@ foreach(SDK ${SWIFT_SDKS})
if("${SDK}" STREQUAL "IOS" OR "${SDK}" STREQUAL "TVOS" OR "${SDK}" STREQUAL "WATCHOS")
# These are supported testing SDKs, but their implementation of
# `command_upload_stdlib` is hidden.
- elseif("${SDK}" STREQUAL "ANDROID")
+ elseif("${SDK}" STREQUAL "ANDROID" AND NOT "${SWIFT_HOST_VARIANT}" STREQUAL "android")
+ # This adb setup is only needed when cross-compiling for Android, so the
+ # second check above makes sure we don't bother when the host is Android.
if("${SWIFT_ANDROID_DEPLOY_DEVICE_PATH}" STREQUAL "")
message(FATAL_ERROR
"When running Android host tests, you must specify the directory on the device "
diff --git a/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake b/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
index a544e07e8a..38e017fe7e 100644
--- a/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
+++ b/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
@@ -181,6 +181,13 @@ macro(add_sourcekit_library name)
endif()
endif()
+ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
+ if(SOURCEKITLIB_SHARED)
+ set_target_properties(${name} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
+ set_target_properties(${name} PROPERTIES INSTALL_RPATH "$ORIGIN/../lib/swift/android")
+ endif()
+ endif()
+
if("${SOURCEKITLIB_INSTALL_IN_COMPONENT}" STREQUAL "")
if(SOURCEKITLIB_SHARED)
set(SOURCEKITLIB_INSTALL_IN_COMPONENT tools)

View File

@ -0,0 +1,13 @@
diff --git a/swift-corelibs-foundation/CMakeLists.txt b/swift-corelibs-foundation/CMakeLists.txt
index bf434b69..e6e2f3f0 100644
--- a/swift-corelibs-foundation/CMakeLists.txt
+++ b/swift-corelibs-foundation/CMakeLists.txt
@@ -92,7 +92,7 @@ set(libdispatch_ldflags)
if(FOUNDATION_ENABLE_LIBDISPATCH)
set(libdispatch_cflags -I;${FOUNDATION_PATH_TO_LIBDISPATCH_SOURCE};-I;${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}/src/swift;-Xcc;-fblocks)
set(libdispatch_ldflags -L;${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD};-L;${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}/src;-ldispatch;-lswiftDispatch)
- if(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL Android OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ if(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
file(TO_CMAKE_PATH "${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}" FOUNDATION_PATH_TO_LIBDISPATCH_BUILD)
list(APPEND libdispatch_ldflags -Xlinker;-rpath;-Xlinker;${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}/src)
endif()

View File

@ -0,0 +1,23 @@
diff --git a/swift-corelibs-libdispatch/src/CMakeLists.txt b/swift-corelibs-libdispatch/src/CMakeLists.txt
index f71b68f..81c4ade 100644
--- a/swift-corelibs-libdispatch/src/CMakeLists.txt
+++ b/swift-corelibs-libdispatch/src/CMakeLists.txt
@@ -144,6 +144,7 @@ if(ENABLE_SWIFT)
-lBlocksRuntime
-L $<TARGET_LINKER_FILE_DIR:dispatch>
-ldispatch
+ -Xlinker -rpath -Xlinker "\\\$\$ORIGIN"
$<$<AND:$<PLATFORM_ID:Windows>,$<CONFIG:Debug>>:-lmsvcrtd>
$<$<AND:$<PLATFORM_ID:Windows>,$<NOT:$<CONFIG:Debug>>>:-lmsvcrt>
MODULE_NAME
@@ -260,6 +261,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
"-Xlinker -dead_strip"
"-Xlinker -alias_list -Xlinker ${PROJECT_SOURCE_DIR}/xcodeconfig/libdispatch.aliases")
endif()
+
+set_target_properties(dispatch PROPERTIES INSTALL_RPATH "$ORIGIN")
+set_target_properties(dispatch PROPERTIES BUILD_WITH_INSTALL_RPATH YES)
+
dispatch_set_linker(dispatch)
install(TARGETS

View File

@ -0,0 +1,12 @@
diff --git a/swift-corelibs-xctest/CMakeLists.txt b/swift-corelibs-xctest/CMakeLists.txt
index 8c9800f..a29a514 100644
--- a/swift-corelibs-xctest/CMakeLists.txt
+++ b/swift-corelibs-xctest/CMakeLists.txt
@@ -55,6 +55,7 @@ add_swift_library(XCTest
# compatibility with Foundation build_script.py
-L${XCTEST_PATH_TO_FOUNDATION_BUILD}/Foundation
+ -Xlinker -rpath -Xlinker "\\\$\$ORIGIN"
${WORKAROUND_SR9138}
${WORKAROUND_SR9995}

View File

@ -0,0 +1,13 @@
diff --git a/swift/lib/Driver/ToolChains.cpp b/swift/lib/Driver/ToolChains.cpp
index cb86ce837f..aebc688fe1 100644
--- a/swift/lib/Driver/ToolChains.cpp
+++ b/swift/lib/Driver/ToolChains.cpp
@@ -1137,7 +1137,7 @@ void ToolChain::getRuntimeLibraryPaths(SmallVectorImpl<std::string> &runtimeLibP
if (!SDKPath.empty()) {
scratchPath = SDKPath;
llvm::sys::path::append(scratchPath, "usr", "lib", "swift");
- runtimeLibPaths.push_back(scratchPath.str());
+ //runtimeLibPaths.push_back(scratchPath.str());
}
}

View File

@ -0,0 +1,29 @@
diff --git a/swift/lib/Driver/UnixToolChains.cpp b/swift/lib/Driver/UnixToolChains.cpp
index bdc63d1ca72..971e5ded1e2 100644
--- a/swift/lib/Driver/UnixToolChains.cpp
+++ b/swift/lib/Driver/UnixToolChains.cpp
@@ -42,7 +42,8 @@ std::string
toolchains::GenericUnix::sanitizerRuntimeLibName(StringRef Sanitizer,
bool shared) const {
return (Twine("libclang_rt.") + Sanitizer + "-" +
- this->getTriple().getArchName() + ".a")
+ this->getTriple().getArchName() +
+ (this->getTriple().isAndroid() ? "-android" : "") + ".a")
.str();
}
@@ -356,7 +357,13 @@ std::string toolchains::Android::getTargetForLinker() const {
return T.str();
}
-bool toolchains::Android::shouldProvideRPathToLinker() const { return false; }
+bool toolchains::Android::shouldProvideRPathToLinker() const {
+#if defined(__ANDROID__)
+ return true;
+#else
+ return false;
+#endif
+}
std::string toolchains::Cygwin::getDefaultLinker() const {
// Cygwin uses the default BFD linker, even on ARM.

View File

@ -0,0 +1,83 @@
commit 7d0b78d00f6ad5278e9273a10415cf36fe349129
Author: Daniel Rodríguez Troitiño <danielrodriguez@fb.com>
Date: Mon May 6 11:06:51 2019 -0700
[android] Stop leaking FDs in parent test process.
In the Android paths of the spawnChild function, the parent was creating
a pipe that was never closed, which led to FD starvation. In some tests
with a lots of expected crashes, the childs will not spawn anymore since
the linker would not have enough descriptors to open the shared
libraries, while in other tests which closed the child descriptors as
part of the last test, the parent process will hang waiting those
descriptors to be closed, which will never had happened.
The solution is implement the missing parts of the code, which tried to
read from the pipe in the parent side (using select and read, taking
pieces from other parts of the code). This should match the fork/execv
path used by Android and Haiku to the spawn code used by the rest of the
platforms.
This change fixes StdlibUnittest/Stdin.swift,
stdlib/InputStream.swift.gyb,
stdlib/Collection/FlattenCollection.swift.gyb and
stdlib/Collection/LazyFilterCollection.swift.gyb, which were the last 4
tests failing in Android AArch64.
diff --git a/swift/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift b/swift/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
index e31b3993e6..e95e07e142 100644
--- a/swift/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
+++ b/swift/stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
@@ -217,6 +217,10 @@ public func spawnChild(_ args: [String])
if pid == 0 {
// pid of 0 means we are now in the child process.
// Capture the output before executing the program.
+ close(childStdout.readFD)
+ close(childStdin.writeFD)
+ close(childStderr.readFD)
+ close(childToParentPipe.readFD)
dup2(childStdout.writeFD, STDOUT_FILENO)
dup2(childStdin.readFD, STDIN_FILENO)
dup2(childStderr.writeFD, STDERR_FILENO)
@@ -261,6 +265,41 @@ public func spawnChild(_ args: [String])
// Close the pipe when we're done writing the error.
close(childToParentPipe.writeFD)
+ } else {
+ close(childToParentPipe.writeFD)
+
+ // Figure out if the childs call to execve was successful or not.
+ var readfds = _stdlib_fd_set()
+ readfds.set(childToParentPipe.readFD)
+ var writefds = _stdlib_fd_set()
+ var errorfds = _stdlib_fd_set()
+ errorfds.set(childToParentPipe.readFD)
+
+ var ret: CInt
+ repeat {
+ ret = _stdlib_select(&readfds, &writefds, &errorfds, nil)
+ } while ret == -1 && errno == EINTR
+ if ret <= 0 {
+ fatalError("select() returned an error: \(errno)")
+ }
+
+ if readfds.isset(childToParentPipe.readFD) || errorfds.isset(childToParentPipe.readFD) {
+ var childErrno: CInt = 0
+ let readResult: ssize_t = withUnsafeMutablePointer(to: &childErrno) {
+ return read(childToParentPipe.readFD, $0, MemoryLayout.size(ofValue: $0.pointee))
+ }
+ if readResult == 0 {
+ // We read an EOF indicating that the child's call to execve was successful.
+ } else if readResult < 0 {
+ fatalError("read() returned error: \(errno)")
+ } else {
+ // We read an error from the child.
+ print(String(cString: strerror(childErrno)))
+ preconditionFailure("execve() failed")
+ }
+ }
+
+ close(childToParentPipe.readFD)
}
#else
var fileActions = _make_posix_spawn_file_actions_t()

View File

@ -0,0 +1,141 @@
diff --git a/swift/stdlib/public/Platform/glibc.modulemap.gyb b/swift/stdlib/public/Platform/glibc.modulemap.gyb
index b024b92f7f..a460615e46 100644
--- a/swift/stdlib/public/Platform/glibc.modulemap.gyb
+++ b/swift/stdlib/public/Platform/glibc.modulemap.gyb
@@ -47,13 +47,13 @@ module SwiftGlibc [system] {
export *
}
% end
-% if CMAKE_SDK in ["LINUX", "FREEBSD", "CYGWIN", "HAIKU"]:
+% if CMAKE_SDK in ["LINUX", "FREEBSD", "CYGWIN", "HAIKU", "ANDROID"]:
module complex {
header "${GLIBC_INCLUDE_PATH}/complex.h"
export *
}
% end
-% if CMAKE_SDK in ["LINUX", "CYGWIN"]:
+% if CMAKE_SDK in ["LINUX", "CYGWIN", "ANDROID"]:
module pty {
header "${GLIBC_INCLUDE_PATH}/pty.h"
export *
@@ -181,7 +181,7 @@ module SwiftGlibc [system] {
// POSIX
module POSIX {
-% if CMAKE_SDK in ["LINUX", "CYGWIN"]:
+% if CMAKE_SDK in ["LINUX", "CYGWIN", "ANDROID"]:
module wait {
header "${GLIBC_INCLUDE_PATH}/wait.h"
export *
@@ -210,8 +210,26 @@ module SwiftGlibc [system] {
export *
}
% end
+% if CMAKE_SDK == "ANDROID":
+ module cpio {
+ header "${GLIBC_INCLUDE_PATH}/cpio.h"
+ export *
+ }
+ module nl_types {
+ header "${GLIBC_INCLUDE_PATH}/nl_types.h"
+ export *
+ }
+ module bits {
+ export *
-% if CMAKE_SDK in ["LINUX", "FREEBSD", "CYGWIN"]:
+ module fcntl {
+ header "${GLIBC_INCLUDE_PATH}/bits/fcntl.h"
+ export *
+ }
+ }
+% end
+
+% if CMAKE_SDK in ["LINUX", "FREEBSD", "CYGWIN", "ANDROID"]:
module ftw {
header "${GLIBC_INCLUDE_PATH}/ftw.h"
export *
@@ -228,10 +246,12 @@ module SwiftGlibc [system] {
header "${GLIBC_INCLUDE_PATH}/langinfo.h"
export *
}
+% if CMAKE_SDK != "ANDROID":
module monetary {
header "${GLIBC_INCLUDE_PATH}/monetary.h"
export *
}
+% end
module netdb {
header "${GLIBC_INCLUDE_PATH}/netdb.h"
export *
@@ -256,6 +276,7 @@ module SwiftGlibc [system] {
header "${GLIBC_INCLUDE_PATH}/tar.h"
export *
}
+% if CMAKE_SDK != "ANDROID":
module utmpx {
header "${GLIBC_INCLUDE_PATH}/utmpx.h"
export *
@@ -265,6 +286,7 @@ module SwiftGlibc [system] {
export *
}
% end
+% end
% if CMAKE_SDK == "HAIKU":
module ftw {
@@ -393,11 +415,16 @@ module SwiftGlibc [system] {
module sys {
export *
-% if CMAKE_SDK in ["LINUX", "FREEBSD", "CYGWIN", "HAIKU"]:
+% if CMAKE_SDK in ["LINUX", "FREEBSD", "CYGWIN", "HAIKU", "ANDROID"]:
+ module cdefs {
+ header "${GLIBC_ARCH_INCLUDE_PATH}/sys/cdefs.h"
+ export *
+ }
module file {
header "${GLIBC_ARCH_INCLUDE_PATH}/sys/file.h"
export *
}
+% if CMAKE_SDK != "ANDROID":
module sem {
header "${GLIBC_ARCH_INCLUDE_PATH}/sys/sem.h"
export *
@@ -407,6 +434,7 @@ module SwiftGlibc [system] {
header "${GLIBC_ARCH_INCLUDE_PATH}/sys/shm.h"
export *
}
+% end
% end
module statvfs {
header "${GLIBC_ARCH_INCLUDE_PATH}/sys/statvfs.h"
@@ -474,7 +502,7 @@ module SwiftGlibc [system] {
header "${GLIBC_ARCH_INCLUDE_PATH}/sys/un.h"
export *
}
-% if CMAKE_SDK in ["LINUX"]:
+% if CMAKE_SDK in ["LINUX", "ANDROID"]:
module user {
header "${GLIBC_ARCH_INCLUDE_PATH}/sys/user.h"
export *
@@ -489,7 +517,7 @@ module SwiftGlibc [system] {
export *
}
}
-% if CMAKE_SDK in ["LINUX", "FREEBSD"]:
+% if CMAKE_SDK in ["LINUX", "FREEBSD", "ANDROID"]:
module sysexits {
header "${GLIBC_INCLUDE_PATH}/sysexits.h"
export *
@@ -510,8 +538,10 @@ module SwiftGlibc [system] {
}
}
+% if CMAKE_SDK != "ANDROID":
module CUUID [system] {
header "${GLIBC_INCLUDE_PATH}/uuid/uuid.h"
link "uuid"
export *
}
+% end

View File

@ -0,0 +1,35 @@
commit 799eb632c86f0171300f9b30f0f8d6586bdc3310
Author: Alex Langford <apl@fb.com>
Date: Tue Apr 2 12:04:19 2019 -0700
[CMake] Make SourceKit respect link_libraries and library_search_directories
add_sourcekit_default_compiler_flags was invoking
_add_variant_link_flags and getting link flags but not actually using
the link_libraries or library_search_directories. In android builds,
this means that the correct libc++ is not being linked against.
diff --git a/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake b/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
index c1535aa2d3..1f7eebe40f 100644
--- a/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
+++ b/swift/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
@@ -66,7 +66,9 @@ function(add_sourcekit_default_compiler_flags target)
ENABLE_LTO "${SWIFT_TOOLS_ENABLE_LTO}"
LTO_OBJECT_NAME "${target}-${sdk}-${arch}"
ANALYZE_CODE_COVERAGE "${analyze_code_coverage}"
- RESULT_VAR_NAME link_flags)
+ RESULT_VAR_NAME link_flags
+ LINK_LIBRARIES_VAR_NAME link_libraries
+ LIBRARY_SEARCH_DIRECTORIES_VAR_NAME library_search_directories)
# Convert variables to space-separated strings.
_list_escape_for_shell("${c_compile_flags}" c_compile_flags)
@@ -77,6 +79,8 @@ function(add_sourcekit_default_compiler_flags target)
COMPILE_FLAGS " ${c_compile_flags} -fblocks")
set_property(TARGET "${target}" APPEND_STRING PROPERTY
LINK_FLAGS " ${link_flags}")
+ set_property(TARGET "${target}" APPEND PROPERTY LINK_LIBRARIES ${link_libraries})
+ swift_target_link_search_directories("${target}" "${library_search_directories}")
endfunction()
# Add a new SourceKit library.

View File

@ -0,0 +1,511 @@
diff --git a/swiftpm/Sources/Basic/Process.swift b/swiftpm/Sources/Basic/Process.swift
index f388c769..573e2e3c 100644
--- a/swiftpm/Sources/Basic/Process.swift
+++ b/swiftpm/Sources/Basic/Process.swift
@@ -268,7 +268,7 @@ public final class Process: ObjectIdentifierProtocol {
}
// Initialize the spawn attributes.
- #if canImport(Darwin)
+ #if canImport(Darwin) || os(Android)
var attributes: posix_spawnattr_t? = nil
#else
var attributes = posix_spawnattr_t()
@@ -313,7 +313,7 @@ public final class Process: ObjectIdentifierProtocol {
posix_spawnattr_setflags(&attributes, Int16(flags))
// Setup the file actions.
- #if canImport(Darwin)
+ #if canImport(Darwin) || os(Android)
var fileActions: posix_spawn_file_actions_t? = nil
#else
var fileActions = posix_spawn_file_actions_t()
diff --git a/swiftpm/Sources/Build/BuildPlan.swift b/swiftpm/Sources/Build/BuildPlan.swift
index 8ad4bdf9..29c8e9b9 100644
--- a/swiftpm/Sources/Build/BuildPlan.swift
+++ b/swiftpm/Sources/Build/BuildPlan.swift
@@ -214,6 +214,8 @@ public struct BuildParameters {
var currentPlatform: PackageModel.Platform {
if self.triple.isDarwin() {
return .macOS
+ } else if self.triple.isAndroid() {
+ return .android
} else {
return .linux
}
diff --git a/swiftpm/Sources/Build/Triple.swift b/swiftpm/Sources/Build/Triple.swift
index 1a0e3095..54bc179e 100644
--- a/swiftpm/Sources/Build/Triple.swift
+++ b/swiftpm/Sources/Build/Triple.swift
@@ -61,7 +61,7 @@ public struct Triple {
public enum ABI: String {
case unknown
- case android = "androideabi"
+ case android
}
public init(_ string: String) throws {
@@ -81,8 +81,7 @@ public struct Triple {
throw Error.unknownOS
}
- let abiString = components.count > 3 ? components[3] : nil
- let abi = abiString.flatMap(ABI.init)
+ let abi = components.count > 3 ? Triple.parseABI(components[3]) : nil
self.tripleString = string
self.arch = arch
@@ -101,6 +100,17 @@ public struct Triple {
return nil
}
+ fileprivate static func parseABI(_ string: String) -> ABI? {
+ if string.hasPrefix(ABI.android.rawValue) {
+ return ABI.android
+ }
+ return nil
+ }
+
+ public func isAndroid() -> Bool {
+ return os == .linux && abi == .android
+ }
+
public func isDarwin() -> Bool {
return vendor == .apple || os == .macOS || os == .darwin
}
@@ -128,7 +132,10 @@ public struct Triple {
public static let s390xLinux = try! Triple("s390x-unknown-linux")
public static let arm64Linux = try! Triple("aarch64-unknown-linux")
public static let armLinux = try! Triple("armv7-unknown-linux-gnueabihf")
- public static let android = try! Triple("armv7-unknown-linux-androideabi")
+ public static let armAndroid = try! Triple("armv7a-unknown-linux-androideabi")
+ public static let arm64Android = try! Triple("aarch64-unknown-linux-android")
+ public static let x86_64Android = try! Triple("x86_64-unknown-linux-android")
+ public static let i686Android = try! Triple("i686-unknown-linux-android")
public static let windows = try! Triple("x86_64-unknown-windows-msvc")
#if os(macOS)
@@ -149,6 +156,16 @@ public struct Triple {
#elseif arch(arm)
public static let hostTriple: Triple = .armLinux
#endif
+ #elseif os(Android)
+ #if arch(arm)
+ public static let hostTriple: Triple = .armAndroid
+ #elseif arch(arm64)
+ public static let hostTriple: Triple = .arm64Android
+ #elseif arch(x86_64)
+ public static let hostTriple: Triple = .x86_64Android
+ #elseif arch(i386)
+ public static let hostTriple: Triple = .i686Android
+ #endif
#endif
}
diff --git a/swiftpm/Sources/Commands/SwiftTool.swift b/swiftpm/Sources/Commands/SwiftTool.swift
index 69865506..16374704 100644
--- a/swiftpm/Sources/Commands/SwiftTool.swift
+++ b/swiftpm/Sources/Commands/SwiftTool.swift
@@ -402,6 +402,12 @@ public class SwiftTool<Options: ToolOptions> {
action.__sigaction_u.__sa_handler = SIG_DFL
sigaction(SIGINT, &action, nil)
kill(getpid(), SIGINT)
+ #elseif os(Android)
+ // Install the default signal handler.
+ var action = sigaction()
+ action.sa_handler = SIG_DFL
+ sigaction(SIGINT, &action, nil)
+ kill(getpid(), SIGINT)
#else
var action = sigaction()
action.__sigaction_handler = unsafeBitCast(
diff --git a/swiftpm/Sources/PackageDescription4/Package.swift b/swiftpm/Sources/PackageDescription4/Package.swift
index 51463e92..ce29b49c 100644
--- a/swiftpm/Sources/PackageDescription4/Package.swift
+++ b/swiftpm/Sources/PackageDescription4/Package.swift
@@ -8,7 +8,7 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
-#if os(Linux)
+#if canImport(Glibc)
import Glibc
#elseif os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
import Darwin.C
diff --git a/swiftpm/Sources/PackageDescription4/SupportedPlatforms.swift b/swiftpm/Sources/PackageDescription4/SupportedPlatforms.swift
index 9e8398dd..34c62c62 100644
--- a/swiftpm/Sources/PackageDescription4/SupportedPlatforms.swift
+++ b/swiftpm/Sources/PackageDescription4/SupportedPlatforms.swift
@@ -25,6 +25,7 @@ public struct Platform: Encodable {
public static let tvOS: Platform = Platform(name: "tvos")
public static let watchOS: Platform = Platform(name: "watchos")
public static let linux: Platform = Platform(name: "linux")
+ public static let android: Platform = Platform(name: "android")
}
/// A platform that the Swift package supports.
diff --git a/swiftpm/Sources/PackageLoading/ManifestLoader.swift b/swiftpm/Sources/PackageLoading/ManifestLoader.swift
index 824db1cb..079560a8 100644
--- a/swiftpm/Sources/PackageLoading/ManifestLoader.swift
+++ b/swiftpm/Sources/PackageLoading/ManifestLoader.swift
@@ -479,7 +479,7 @@ public final class ManifestLoader: ManifestLoaderProtocol {
/// Returns the extra manifest args required during SwiftPM's own bootstrap.
private func bootstrapArgs() -> [String] {
- #if !os(Linux)
+ #if !os(Linux) && !os(Android)
return []
#else
// The Linux bots require extra arguments in order to locate the corelibs.
@@ -494,8 +494,8 @@ public final class ManifestLoader: ManifestLoaderProtocol {
}
// Construct the required search paths relative to the build directory.
- let libdir = buildPath.appending(RelativePath(".bootstrap/lib/swift/linux"))
- let incdir = libdir.appending(component: "x86_64")
+ let libdir = buildPath.appending(RelativePath(".bootstrap/lib/swift/android"))
+ let incdir = libdir.appending(component: "aarch64")
let dispatchIncdir = incdir.appending(component: "dispatch")
return [
diff --git a/swiftpm/Sources/PackageModel/Platform.swift b/swiftpm/Sources/PackageModel/Platform.swift
index 3f56355a..66d14321 100644
--- a/swiftpm/Sources/PackageModel/Platform.swift
+++ b/swiftpm/Sources/PackageModel/Platform.swift
@@ -29,7 +29,7 @@ public final class PlatformRegistry {
/// The static list of known platforms.
private static var _knownPlatforms: [Platform] {
- return [.macOS, .iOS, .tvOS, .watchOS, .linux]
+ return [.macOS, .iOS, .tvOS, .watchOS, .linux, .android]
}
}
@@ -55,6 +55,7 @@ public struct Platform: Equatable, Hashable {
public static let tvOS: Platform = Platform(name: "tvos", oldestSupportedVersion: "9.0")
public static let watchOS: Platform = Platform(name: "watchos", oldestSupportedVersion: "2.0")
public static let linux: Platform = Platform(name: "linux", oldestSupportedVersion: .unknown)
+ public static let android: Platform = Platform(name: "android", oldestSupportedVersion: .unknown)
}
/// Represents a platform version.
diff --git a/swiftpm/Sources/SPMLibc/libc.swift b/swiftpm/Sources/SPMLibc/libc.swift
index 4f32b5a4..e346b728 100644
--- a/swiftpm/Sources/SPMLibc/libc.swift
+++ b/swiftpm/Sources/SPMLibc/libc.swift
@@ -8,7 +8,7 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
-#if os(Linux)
+#if canImport(Glibc)
@_exported import Glibc
#else
@_exported import Darwin.C
diff --git a/swiftpm/Sources/SPMUtility/FSWatch.swift b/swiftpm/Sources/SPMUtility/FSWatch.swift
index 70b12765..98b95cc0 100644
--- a/swiftpm/Sources/SPMUtility/FSWatch.swift
+++ b/swiftpm/Sources/SPMUtility/FSWatch.swift
@@ -428,55 +428,76 @@ public final class Inotify {
// FIXME: <rdar://problem/45794219> Swift should provide shims for FD_ macros
private func FD_ZERO(_ set: inout fd_set) {
+ #if os(Android)
+ set.fds_bits = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+ #else
set.__fds_bits = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+ #endif
}
private func FD_SET(_ fd: Int32, _ set: inout fd_set) {
let intOffset = Int(fd / 16)
let bitOffset = Int(fd % 16)
+ #if os(Android)
+ var fd_bits = set.fds_bits
+ let mask: UInt = 1 << bitOffset
+ #else
+ var fd_bits = set.__fds_bits
let mask = 1 << bitOffset
+ #endif
switch intOffset {
- case 0: set.__fds_bits.0 = set.__fds_bits.0 | mask
- case 1: set.__fds_bits.1 = set.__fds_bits.1 | mask
- case 2: set.__fds_bits.2 = set.__fds_bits.2 | mask
- case 3: set.__fds_bits.3 = set.__fds_bits.3 | mask
- case 4: set.__fds_bits.4 = set.__fds_bits.4 | mask
- case 5: set.__fds_bits.5 = set.__fds_bits.5 | mask
- case 6: set.__fds_bits.6 = set.__fds_bits.6 | mask
- case 7: set.__fds_bits.7 = set.__fds_bits.7 | mask
- case 8: set.__fds_bits.8 = set.__fds_bits.8 | mask
- case 9: set.__fds_bits.9 = set.__fds_bits.9 | mask
- case 10: set.__fds_bits.10 = set.__fds_bits.10 | mask
- case 11: set.__fds_bits.11 = set.__fds_bits.11 | mask
- case 12: set.__fds_bits.12 = set.__fds_bits.12 | mask
- case 13: set.__fds_bits.13 = set.__fds_bits.13 | mask
- case 14: set.__fds_bits.14 = set.__fds_bits.14 | mask
- case 15: set.__fds_bits.15 = set.__fds_bits.15 | mask
+ case 0: fd_bits.0 = fd_bits.0 | mask
+ case 1: fd_bits.1 = fd_bits.1 | mask
+ case 2: fd_bits.2 = fd_bits.2 | mask
+ case 3: fd_bits.3 = fd_bits.3 | mask
+ case 4: fd_bits.4 = fd_bits.4 | mask
+ case 5: fd_bits.5 = fd_bits.5 | mask
+ case 6: fd_bits.6 = fd_bits.6 | mask
+ case 7: fd_bits.7 = fd_bits.7 | mask
+ case 8: fd_bits.8 = fd_bits.8 | mask
+ case 9: fd_bits.9 = fd_bits.9 | mask
+ case 10: fd_bits.10 = fd_bits.10 | mask
+ case 11: fd_bits.11 = fd_bits.11 | mask
+ case 12: fd_bits.12 = fd_bits.12 | mask
+ case 13: fd_bits.13 = fd_bits.13 | mask
+ case 14: fd_bits.14 = fd_bits.14 | mask
+ case 15: fd_bits.15 = fd_bits.15 | mask
default: break
}
+ #if os(Android)
+ set.fds_bits = fd_bits
+ #else
+ set.__fds_bits = fd_bits
+ #endif
}
private func FD_ISSET(_ fd: Int32, _ set: inout fd_set) -> Bool {
let intOffset = Int(fd / 32)
let bitOffset = Int(fd % 32)
+ #if os(Android)
+ let fd_bits = set.fds_bits
+ let mask: UInt = 1 << bitOffset
+ #else
+ let fd_bits = set.__fds_bits
let mask = 1 << bitOffset
+ #endif
switch intOffset {
- case 0: return set.__fds_bits.0 & mask != 0
- case 1: return set.__fds_bits.1 & mask != 0
- case 2: return set.__fds_bits.2 & mask != 0
- case 3: return set.__fds_bits.3 & mask != 0
- case 4: return set.__fds_bits.4 & mask != 0
- case 5: return set.__fds_bits.5 & mask != 0
- case 6: return set.__fds_bits.6 & mask != 0
- case 7: return set.__fds_bits.7 & mask != 0
- case 8: return set.__fds_bits.8 & mask != 0
- case 9: return set.__fds_bits.9 & mask != 0
- case 10: return set.__fds_bits.10 & mask != 0
- case 11: return set.__fds_bits.11 & mask != 0
- case 12: return set.__fds_bits.12 & mask != 0
- case 13: return set.__fds_bits.13 & mask != 0
- case 14: return set.__fds_bits.14 & mask != 0
- case 15: return set.__fds_bits.15 & mask != 0
+ case 0: return fd_bits.0 & mask != 0
+ case 1: return fd_bits.1 & mask != 0
+ case 2: return fd_bits.2 & mask != 0
+ case 3: return fd_bits.3 & mask != 0
+ case 4: return fd_bits.4 & mask != 0
+ case 5: return fd_bits.5 & mask != 0
+ case 6: return fd_bits.6 & mask != 0
+ case 7: return fd_bits.7 & mask != 0
+ case 8: return fd_bits.8 & mask != 0
+ case 9: return fd_bits.9 & mask != 0
+ case 10: return fd_bits.10 & mask != 0
+ case 11: return fd_bits.11 & mask != 0
+ case 12: return fd_bits.12 & mask != 0
+ case 13: return fd_bits.13 & mask != 0
+ case 14: return fd_bits.14 & mask != 0
+ case 15: return fd_bits.15 & mask != 0
default: return false
}
}
diff --git a/swiftpm/Sources/SPMUtility/IndexStore.swift b/swiftpm/Sources/SPMUtility/IndexStore.swift
index 99814fba..ad99f692 100644
--- a/swiftpm/Sources/SPMUtility/IndexStore.swift
+++ b/swiftpm/Sources/SPMUtility/IndexStore.swift
@@ -191,7 +191,11 @@ public final class IndexStoreAPI {
public init(dylib path: AbsolutePath) throws {
self.path = path
+ #if os(Android)
+ self.dylib = try dlopen(path.pathString, mode: [.lazy, .local, .first])
+ #else
self.dylib = try dlopen(path.pathString, mode: [.lazy, .local, .first, .deepBind])
+ #endif
func dlsym_required<T>(_ handle: DLHandle, symbol: String) throws -> T {
guard let sym: T = dlsym(handle, symbol: symbol) else {
diff --git a/swiftpm/Sources/SPMUtility/InterruptHandler.swift b/swiftpm/Sources/SPMUtility/InterruptHandler.swift
index 3eb32a29..2d477d78 100644
--- a/swiftpm/Sources/SPMUtility/InterruptHandler.swift
+++ b/swiftpm/Sources/SPMUtility/InterruptHandler.swift
@@ -39,6 +39,8 @@ public final class InterruptHandler {
var action = sigaction()
#if canImport(Darwin)
action.__sigaction_u.__sa_handler = signalHandler
+ #elseif os(Android)
+ action.sa_handler = signalHandler
#else
action.__sigaction_handler = unsafeBitCast(
signalHandler,
diff --git a/swiftpm/Sources/SPMUtility/Platform.swift b/swiftpm/Sources/SPMUtility/Platform.swift
index 29db029b..15907ff6 100644
--- a/swiftpm/Sources/SPMUtility/Platform.swift
+++ b/swiftpm/Sources/SPMUtility/Platform.swift
@@ -13,6 +13,7 @@ import Foundation
/// Recognized Platform types.
public enum Platform {
+ case android
case darwin
case linux(LinuxFlavor)
@@ -33,6 +34,10 @@ public enum Platform {
if localFileSystem.isFile(AbsolutePath("/etc/debian_version")) {
return .linux(.debian)
}
+ if localFileSystem.isFile(AbsolutePath("/system/bin/toolbox")) ||
+ localFileSystem.isFile(AbsolutePath("/system/bin/toybox")) {
+ return .android
+ }
default:
return nil
}
@@ -60,6 +65,7 @@ public enum Platform {
/// Returns the value of given path variable using `getconf` utility.
///
/// - Note: This method returns `nil` if the value is an invalid path.
+ #if os(macOS)
private static func getConfstr(_ name: Int32) -> AbsolutePath? {
let len = confstr(name, nil, 0)
let tmp = UnsafeMutableBufferPointer(start: UnsafeMutablePointer<Int8>.allocate(capacity: len), count:len)
@@ -69,4 +75,5 @@ public enum Platform {
guard value.hasSuffix(AbsolutePath.root.pathString) else { return nil }
return resolveSymlinks(AbsolutePath(value))
}
+ #endif
}
diff --git a/swiftpm/Sources/SPMUtility/dlopen.swift b/swiftpm/Sources/SPMUtility/dlopen.swift
index a36b0052..f73da65d 100644
--- a/swiftpm/Sources/SPMUtility/dlopen.swift
+++ b/swiftpm/Sources/SPMUtility/dlopen.swift
@@ -60,8 +60,10 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
public static let deepBind: DLOpenFlags = DLOpenFlags(rawValue: 0)
#else
public static let first: DLOpenFlags = DLOpenFlags(rawValue: 0)
+ #if !os(Android)
public static let deepBind: DLOpenFlags = DLOpenFlags(rawValue: RTLD_DEEPBIND)
#endif
+ #endif
#endif
public var rawValue: Int32
diff --git a/swiftpm/Sources/PackageLoading/Target+PkgConfig.swift b/swiftpm/Sources/PackageLoading/Target+PkgConfig.swift
index c0918cc6..aaabfa89 100644
--- a/swiftpm/Sources/PackageLoading/Target+PkgConfig.swift
+++ b/swiftpm/Sources/PackageLoading/Target+PkgConfig.swift
@@ -118,6 +118,9 @@ extension SystemPackageProviderDescription {
if case .linux(.debian) = platform {
return true
}
+ if case .android = platform {
+ return true
+ }
}
return false
}
diff --git a/swiftpm/Utilities/bootstrap b/swiftpm/Utilities/bootstrap
index b6343c3f..92be12c6 100755
--- a/swiftpm/Utilities/bootstrap
+++ b/swiftpm/Utilities/bootstrap
@@ -273,6 +273,10 @@ class Target(object):
if args.llbuild_link_framework:
other_args.extend(["-F", args.llbuild_build_dir])
+ # Don't use GNU strerror_r on Android.
+ if 'ANDROID_DATA' in os.environ:
+ other_args.extend(["-Xcc", "-U_GNU_SOURCE"])
+
print(" import-paths: %s" % json.dumps(import_paths), file=output)
print(" other-args: %s" % json.dumps(other_args),
file=output)
@@ -571,7 +575,7 @@ class llbuild(object):
link_command.extend(["-Xlinker", "-l%s" % (lib,)])
if platform.system() == 'Linux':
link_command.extend(
- ["-Xlinker", "-rpath=$ORIGIN/../lib/swift/linux"])
+ ["-Xlinker", "-rpath=$ORIGIN/../lib/swift/android", "-Xlinker", "-landroid-spawn"])
if self.args.foundation_path:
link_command.extend(["-L", self.args.foundation_path])
if self.args.libdispatch_build_dir:
@@ -675,8 +679,9 @@ def process_runtime_libraries(build, args, lib_path):
cmd = [args.swiftc_path, "-emit-library", "-o", runtime_lib_path,
"-Xlinker", "--whole-archive",
"-Xlinker", input_lib_path,
- "-Xlinker", "--no-whole-archive", "-lswiftGlibc",
- "-Xlinker", "-rpath=$ORIGIN/../../linux"]
+ "-Xlinker", "--no-whole-archive", "-Xlinker", "-L%s" % args.foundation_path,
+ "-lswiftGlibc", "-lFoundation",
+ "-Xlinker", "-rpath=$ORIGIN/../../android"]
# We need to pass one swift file here to bypass the "no input files"
# error.
@@ -737,8 +742,8 @@
def get_clang_path():
try:
if os.getenv("CC"):
- clang_path=os.path.realpath(os.getenv("CC"))
- return clang_path
+ return subprocess.check_output(["which", os.getenv("CC")],
+ universal_newlines=True).strip()
elif platform.system() == 'Darwin':
return subprocess.check_output(["xcrun", "--find", "clang"],
stderr=subprocess.PIPE, universal_newlines=True).strip()
@@ -1030,7 +1035,14 @@ def main():
if platform.system() == 'Darwin':
build_target = "x86_64-apple-macosx"
elif platform.system() == 'Linux':
- if platform.machine() == 'x86_64':
+ if 'ANDROID_DATA' in os.environ:
+ if platform.machine().startswith("armv7"):
+ build_target = 'armv7-unknown-linux-androideabi'
+ elif platform.machine() == 'aarch64':
+ build_target = 'aarch64-unknown-linux-android'
+ else:
+ raise SystemExit("ERROR: unsupported Android platform:",platform.machine())
+ elif platform.machine() == 'x86_64':
build_target = "x86_64-unknown-linux"
elif platform.machine() == "i686":
build_target = "i686-unknown-linux"
@@ -1159,8 +1172,8 @@ def main():
symlink_force(os.path.join(sandbox_path, "lib"), usrdir)
if args.foundation_path and args.libdispatch_build_dir and args.xctest_path:
- libswiftdir = os.path.join(sandbox_path, "lib", "swift", "linux")
- libincludedir = os.path.join(libswiftdir, "x86_64")
+ libswiftdir = os.path.join(sandbox_path, "lib", "swift", "android")
+ libincludedir = os.path.join(libswiftdir, "aarch64")
mkdir_p(libswiftdir)
mkdir_p(libincludedir)
@@ -1210,10 +1223,10 @@ def main():
embed_rpath = args.stdlib_rpath
else:
if platform.system() == 'Linux':
- embed_rpath = "$ORIGIN/../lib/swift/linux"
+ embed_rpath = "$ORIGIN/../lib/swift/android"
else:
embed_rpath = "@executable_path/../lib/swift/macosx"
- build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", embed_rpath])
+ build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", embed_rpath, "-Xlinker", "-landroid-spawn"])
if args.verbose:
build_flags.append("-v")
@@ -1236,6 +1248,10 @@ def main():
# Add an RPATH, so that the tests can be run directly.
build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", faketoolchain_libdir])
+ # Don't use GNU strerror_r on Android.
+ if 'ANDROID_DATA' in os.environ:
+ build_flags.extend(["-Xswiftc", "-Xcc", "-Xswiftc", "-U_GNU_SOURCE"])
+
# Add llbuild import flags.
for import_path in llbuild_import_paths(args):
build_flags.extend(["-Xswiftc", "-I%s" % import_path])

View File

@ -0,0 +1,160 @@
commit caea53ad329a79fce2ac2b3eadf7c8ba92b903fa
Author: Gwen Mittertreiner <gwen.mittertreiner@gmail.com>
Date: Sun Apr 7 13:23:17 2019 -0700
Remove use of fts
Replace the use of fts with Foundation's Directory Enumerator, which (on
Darwin/Linux), calls fts instead, but is cross platform for Windows.
diff --git a/swiftpm/Sources/Basic/FileSystem.swift b/swiftpm/Sources/Basic/FileSystem.swift
index 958eaaf4..1b9e01a0 100644
--- a/swiftpm/Sources/Basic/FileSystem.swift
+++ b/swiftpm/Sources/Basic/FileSystem.swift
@@ -88,16 +88,18 @@ public enum FileMode {
case userUnWritable
case userWritable
case executable
-
- /// File mode as it would be passed to `chmod`.
- public var cliArgument: String {
+
+ internal var setMode: (Int16) -> Int16 {
switch self {
case .userUnWritable:
- return "u-w"
+ // r-x rwx rwx
+ return {$0 & 0o577}
case .userWritable:
- return "u+w"
+ // -w- --- ---
+ return {$0 | 0o200}
case .executable:
- return "+x"
+ // --x --x --x
+ return {$0 | 0o111}
}
}
}
@@ -375,86 +377,39 @@ private class LocalFileSystem: FileSystem {
}
func chmod(_ mode: FileMode, path: AbsolutePath, options: Set<FileMode.Option>) throws {
- #if os(macOS)
- // Get the mode we need to set.
- guard let setMode = setmode(mode.cliArgument) else {
- throw FileSystemError(errno: errno)
- }
- defer { setMode.deallocate() }
+ guard exists(path) else { return }
+ func setMode(path: String) throws {
+ // Skip if only files should be changed.
+ if options.contains(.onlyFiles) && isDirectory(AbsolutePath(path)) {
+ return
+ }
- let recursive = options.contains(.recursive)
- // If we're in recursive mode, do physical walk otherwise logical.
- let ftsOptions = recursive ? FTS_PHYSICAL : FTS_LOGICAL
+ let attrs = try FileManager.default.attributesOfItem(atPath: path)
- // Get handle to the file hierarchy we want to traverse.
- let paths = CStringArray([path.pathString])
- guard let ftsp = fts_open(paths.cArray, ftsOptions, nil) else {
- throw FileSystemError(errno: errno)
+ // Compute the new mode for this file.
+ let currentMode = attrs[.posixPermissions] as! Int16
+ let newMode = mode.setMode(currentMode)
+ guard newMode != currentMode else { return }
+ try FileManager.default.setAttributes([.posixPermissions : newMode],
+ ofItemAtPath: path)
}
- defer { fts_close(ftsp) }
-
- // Start traversing.
- while let p = fts_read(ftsp) {
-
- switch Int32(p.pointee.fts_info) {
-
- // A directory being visited in pre-order.
- case FTS_D:
- // If we're not recursing, skip the contents of the directory.
- if !recursive {
- fts_set(ftsp, p, FTS_SKIP)
- }
- continue
-
- // A directory couldn't be read.
- case FTS_DNR:
- // FIXME: We should warn here.
- break
-
- // There was an error.
- case FTS_ERR:
- fallthrough
- // No stat(2) information was available.
- case FTS_NS:
- // FIXME: We should warn here.
- continue
+ try setMode(path: path.pathString)
+ guard isDirectory(path) else { return }
- // A symbolic link.
- case FTS_SL:
- fallthrough
-
- // A symbolic link with a non-existent target.
- case FTS_SLNONE:
- // The only symlinks that end up here are ones that don't point
- // to anything and ones that we found doing a physical walk.
- continue
-
- default:
- break
- }
-
- // Compute the new mode for this file.
- let currentMode = mode_t(p.pointee.fts_statp.pointee.st_mode)
-
- // Skip if only files should be changed.
- if options.contains(.onlyFiles) && (currentMode & S_IFMT) == S_IFDIR {
- continue
- }
+ guard let traverse = FileManager.default.enumerator(
+ at: URL(fileURLWithPath: path.pathString),
+ includingPropertiesForKeys: nil) else {
+ throw FileSystemError.noEntry
+ }
- // Compute the new mode.
- let newMode = getmode(setMode, currentMode)
- if newMode == currentMode {
- continue
- }
+ if !options.contains(.recursive) {
+ traverse.skipDescendants()
+ }
- // Update the mode.
- //
- // We ignore the errors for now but we should have a way to report back.
- _ = SPMLibc.chmod(p.pointee.fts_accpath, newMode)
+ while let path = traverse.nextObject() {
+ try setMode(path: (path as! URL).path)
}
- #endif
- // FIXME: We only support macOS right now.
}
}
diff --git a/swiftpm/Sources/clibc/include/clibc.h b/swiftpm/Sources/clibc/include/clibc.h
index 7cf808c1..8a90bffa 100644
--- a/swiftpm/Sources/clibc/include/clibc.h
+++ b/swiftpm/Sources/clibc/include/clibc.h
@@ -1,5 +1,3 @@
-#include <fts.h>
-
#if defined(__linux__)
#include <sys/inotify.h>
#endif

View File

@ -0,0 +1,40 @@
diff --git a/swiftpm/Utilities/bootstrap b/swiftpm/Utilities/bootstrap
index a57ddbed..6ce5d321 100755
--- a/swiftpm/Utilities/bootstrap
+++ b/swiftpm/Utilities/bootstrap
@@ -843,14 +843,15 @@ def llbuild_lib_path(args):
llbuild_libdir = os.path.join(args.llbuild_build_dir, "lib")
return llbuild_libdir
-def llbuild_link_args(args):
+def llbuild_link_args(args, add_rpath=True):
build_flags = []
llbuild_libdir = llbuild_lib_path(args)
if args.llbuild_link_framework:
build_flags.extend(["-Xlinker", "-F%s" % llbuild_libdir])
else:
build_flags.extend(["-Xlinker", "-L%s" % llbuild_libdir])
- build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", llbuild_libdir])
+ if add_rpath:
+ build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", llbuild_libdir])
return build_flags
def write_self_hosting_script(path, args):
@@ -1246,7 +1247,7 @@ def main():
build_flags.extend(["-Xlinker", "-L{}".format(faketoolchain_libdir)])
# Add an RPATH, so that the tests can be run directly.
- build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", faketoolchain_libdir])
+ #build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", faketoolchain_libdir])
# Don't use GNU strerror_r on Android.
if 'ANDROID_DATA' in os.environ:
@@ -1272,7 +1273,7 @@ def main():
build_flags.extend(["-Xlinker", "-rpath", "-Xlinker", rpath])
# Add llbuild link flags.
- build_flags.extend(llbuild_link_args(args))
+ build_flags.extend(llbuild_link_args(args, False))
# Enable testing in release mode because SwiftPM's tests uses @testable imports.
#