diff --git a/CoreFoundation/Base.subproj/CFPlatform.c b/CoreFoundation/Base.subproj/CFPlatform.c index 896193f662..c0dc6f4547 100644 --- a/CoreFoundation/Base.subproj/CFPlatform.c +++ b/CoreFoundation/Base.subproj/CFPlatform.c @@ -31,6 +31,10 @@ #endif +#if defined(__ANDROID__) +#include +#endif + #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS #define kCFPlatformInterfaceStringEncoding kCFStringEncodingUTF8 #else @@ -1319,6 +1323,8 @@ _CFThreadRef _CFThreadCreate(const _CFThreadAttributes attrs, void *_Nullable (* CF_SWIFT_EXPORT void _CFThreadSetName(const char *_Nullable name) { #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI pthread_setname_np(name); +#elif defined(__ANDROID__) + prctl(PR_SET_NAME, (unsigned long) name, 0, 0, 0); #elif DEPLOYMENT_TARGET_LINUX pthread_setname_np(pthread_self(), name); #endif @@ -1327,6 +1333,8 @@ CF_SWIFT_EXPORT void _CFThreadSetName(const char *_Nullable name) { CF_SWIFT_EXPORT int _CFThreadGetName(char *buf, int length) { #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI return pthread_getname_np(pthread_self(), buf, length); +#elif defined(__ANDROID__) + prctl(PR_GET_NAME, (unsigned long) buf, 0, 0, 0); #elif DEPLOYMENT_TARGET_LINUX return pthread_getname_np(pthread_self(), buf, length); #endif diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h index 2d208567ba..2651cd89f5 100644 --- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h @@ -27,10 +27,9 @@ #include #include #include -#include -#if __has_include() -#include +#if __has_include() +#include #endif #if __has_include() diff --git a/CoreFoundation/URL.subproj/CFURL.c b/CoreFoundation/URL.subproj/CFURL.c index 191e713c04..709762ffb1 100644 --- a/CoreFoundation/URL.subproj/CFURL.c +++ b/CoreFoundation/URL.subproj/CFURL.c @@ -25,10 +25,10 @@ #include #include #include -#if __has_include() -#include -#else +#if DEPLOYMENT_TARGET_ANDROID #include +#else +#include #endif #include #endif diff --git a/Foundation/Bundle.swift b/Foundation/Bundle.swift index 5c66d379d9..b9daa75e50 100644 --- a/Foundation/Bundle.swift +++ b/Foundation/Bundle.swift @@ -53,8 +53,16 @@ open class Bundle: NSObject { self.init(path: url.path) } - public init(for aClass: AnyClass) { NSUnimplemented() } - +#if os(Android) + public convenience init(for aClass: AnyClass) { + self.init(path: Bundle.main.bundlePath)! + } +#else + public init(for aClass: AnyClass) { + NSUnimplemented() + } +#endif + public init?(identifier: String) { super.init() diff --git a/Foundation/FileManager.swift b/Foundation/FileManager.swift index 6e49d0a25f..bdc29875be 100644 --- a/Foundation/FileManager.swift +++ b/Foundation/FileManager.swift @@ -337,7 +337,8 @@ open class FileManager : NSObject { return result } - + +#if !os(Android) /* attributesOfFileSystemForPath:error: returns an NSDictionary of key/value pairs containing the attributes of the filesystem containing the provided path. If this method returns 'nil', an NSError will be returned by reference in the 'error' parameter. This method does not traverse a terminal symlink. This method replaces fileSystemAttributesAtPath:. @@ -372,7 +373,8 @@ open class FileManager : NSObject { return result } - +#endif + /* createSymbolicLinkAtPath:withDestination:error: returns YES if the symbolic link that point at 'destPath' was able to be created at the location specified by 'path'. If this method returns NO, the link was unable to be created and an NSError will be returned by reference in the 'error' parameter. This method does not traverse a terminal symlink. This method replaces createSymbolicLinkAtPath:pathContent: diff --git a/Foundation/Host.swift b/Foundation/Host.swift index 3c09f7c38f..08b87af2a2 100644 --- a/Foundation/Host.swift +++ b/Foundation/Host.swift @@ -65,6 +65,7 @@ open class Host: NSObject { } internal func _resolveCurrent() { +#if !os(Android) var ifaddr: UnsafeMutablePointer? = nil if getifaddrs(&ifaddr) != 0 { return @@ -88,6 +89,7 @@ open class Host: NSObject { } ifa = ifaValue.ifa_next } +#endif } internal func _resolve() { @@ -138,7 +140,7 @@ open class Host: NSObject { } let sa_len: socklen_t = socklen_t((family == AF_INET6) ? MemoryLayout.size : MemoryLayout.size) let lookupInfo = { (content: inout [String], flags: Int32) in - if getnameinfo(info.ai_addr, sa_len, host, socklen_t(NI_MAXHOST), nil, 0, flags) == 0 { + if getnameinfo(info.ai_addr, sa_len, host, numericCast(NI_MAXHOST), nil, 0, flags) == 0 { content.append(String(cString: host)) } } diff --git a/Foundation/NSLog.swift b/Foundation/NSLog.swift index 1ba978dfff..49013aa565 100644 --- a/Foundation/NSLog.swift +++ b/Foundation/NSLog.swift @@ -33,6 +33,9 @@ public func NSLogv(_ format: String, _ args: CVaListPointer) { CFLog1(kCFLogLevelWarning, message._cfObject) #else CFLog1(Int32(kCFLogLevelWarning), message._cfObject) +#if os(Android) + print(message) +#endif #endif } diff --git a/Foundation/Thread.swift b/Foundation/Thread.swift index 402294da41..b11a62fc2f 100644 --- a/Foundation/Thread.swift +++ b/Foundation/Thread.swift @@ -250,7 +250,7 @@ open class Thread : NSObject { _cancelled = true } - +#if !os(Android) private class func backtraceAddresses(_ body: (UnsafeMutablePointer, Int) -> [T]) -> [T] { // Same as swift/stdlib/public/runtime/Errors.cpp backtrace let maxSupportedStackDepth = 128; @@ -284,6 +284,15 @@ open class Thread : NSObject { return symbols }) } +#else + open class var callStackReturnAddresses: [NSNumber] { + NSUnimplemented() + } + + open class var callStackSymbols: [String] { + NSUnimplemented() + } +#endif } extension NSNotification.Name { diff --git a/Foundation/URLSession/http/EasyHandle.swift b/Foundation/URLSession/http/EasyHandle.swift index b7b7550612..c89946f49c 100644 --- a/Foundation/URLSession/http/EasyHandle.swift +++ b/Foundation/URLSession/http/EasyHandle.swift @@ -57,9 +57,6 @@ internal final class _EasyHandle { fileprivate var pauseState: _PauseState = [] internal var timeoutTimer: _TimeoutSource! internal lazy var errorBuffer = [UInt8](repeating: 0, count: Int(CFURLSessionEasyErrorSize)) - #if os(Android) - static fileprivate var _CAInfoFile: UnsafeMutablePointer? - #endif init(delegate: _EasyHandleDelegate) { self.delegate = delegate @@ -107,7 +104,7 @@ internal protocol _EasyHandleDelegate: class { /// - returns: the number of bytes written to the `data` buffer, or `nil` to stop the current transfer immediately. func fill(writeBuffer buffer: UnsafeMutableBufferPointer) -> _EasyHandle._WriteBufferResult /// The transfer for this handle completed. - /// - parameter errorCode: An NSURLError code, or `nil` if no error occured. + /// - parameter error: An NSError, or `nil` if no error occured. func transferCompleted(withError error: NSError?) /// Seek the input stream to the given position func seekInputStream(to position: UInt64) throws @@ -172,20 +169,20 @@ extension _EasyHandle { let protocols = (CFURLSessionProtocolHTTP | CFURLSessionProtocolHTTPS) try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionPROTOCOLS, protocols).asError() try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionREDIR_PROTOCOLS, protocols).asError() - #if os(Android) - // See https://curl.haxx.se/docs/sslcerts.html - // For SSL to work you need "cacert.pem" to be accessable - // at the path pointed to by the URLSessionCAInfo env var. - // Downloadable here: https://curl.haxx.se/ca/cacert.pem - if let caInfo = _EasyHandle._CAInfoFile { - if String(cString: caInfo) == "UNSAFE_SSL_NOVERIFY" { - try! CFURLSession_easy_setopt_int(rawHandle, CFURLSessionOptionSSL_VERIFYPEER, 0).asError() - } - else { - try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, caInfo).asError() - } +#if os(Android) + // See https://curl.haxx.se/docs/sslcerts.html + // For SSL on Android you need a "cacert.pem" to be + // accessible at the path pointed to by this env var. + // Downloadable here: https://curl.haxx.se/ca/cacert.pem + if let caInfo = getenv("URLSessionCertificateAuthorityInfoFile") { + if String(cString: caInfo) == "INSECURE_SSL_NO_VERIFY" { + try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionSSL_VERIFYPEER, 0).asError() + } + else { + try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, caInfo).asError() } - #endif + } +#endif //TODO: Added in libcurl 7.45.0 //TODO: Set default protocol for schemeless URLs //CURLOPT_DEFAULT_PROTOCOL available only in libcurl 7.45.0 @@ -632,19 +629,6 @@ extension _EasyHandle._CurlStringList { } } -#if os(Android) -extension URLSession { - - public static func setCAInfoFile(_ _CAInfoFile: String) { - free(_EasyHandle._CAInfoFile) - _CAInfoFile.withCString { - _EasyHandle._CAInfoFile = strdup($0) - } - } - -} -#endif - extension CFURLSessionEasyCode : Equatable { public static func ==(lhs: CFURLSessionEasyCode, rhs: CFURLSessionEasyCode) -> Bool { return lhs.value == rhs.value diff --git a/TestFoundation/TestNSNumber.swift b/TestFoundation/TestNSNumber.swift index 28a7b800f7..27cbfa0889 100644 --- a/TestFoundation/TestNSNumber.swift +++ b/TestFoundation/TestNSNumber.swift @@ -1076,7 +1076,7 @@ class TestNSNumber : XCTestCase { XCTAssertEqual(NSNumber(value: UInt.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt.max).stringValue, "4294967295") - XCTAssertEqual(NSNumber(value: UInt.max - 1).stringValue, "4294967294") + XCTAssertEqual(NSNumber(value: UInt.max - 1 as UInt).stringValue, "4294967294") } else if UInt.max == UInt64.max { XCTAssertEqual(NSNumber(value: UInt.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt.min + 1).stringValue, "1") @@ -1097,12 +1097,12 @@ class TestNSNumber : XCTestCase { XCTAssertEqual(NSNumber(value: UInt32.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt32.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt32.max).stringValue, "4294967295") - XCTAssertEqual(NSNumber(value: UInt32.max - 1).stringValue, "4294967294") + XCTAssertEqual(NSNumber(value: UInt32.max - 1 as UInt32).stringValue, "4294967294") XCTAssertEqual(NSNumber(value: UInt64.min).stringValue, "0") XCTAssertEqual(NSNumber(value: UInt64.min + 1).stringValue, "1") XCTAssertEqual(NSNumber(value: UInt64.max).stringValue, "18446744073709551615") - XCTAssertEqual(NSNumber(value: UInt64.max - 1).stringValue, "18446744073709551614") + XCTAssertEqual(NSNumber(value: UInt64.max - 1 as UInt64).stringValue, "18446744073709551614") if Int.max == Int32.max { XCTAssertEqual(NSNumber(value: Int.min).stringValue, "-2147483648") @@ -1134,7 +1134,7 @@ class TestNSNumber : XCTestCase { XCTAssertEqual(NSNumber(value: Int64.min).stringValue, "-9223372036854775808") XCTAssertEqual(NSNumber(value: Int64.min + 1).stringValue, "-9223372036854775807") XCTAssertEqual(NSNumber(value: Int64.max).stringValue, "9223372036854775807") - XCTAssertEqual(NSNumber(value: Int64.max - 1).stringValue, "9223372036854775806") + XCTAssertEqual(NSNumber(value: Int64.max - 1 as Int64).stringValue, "9223372036854775806") } func test_Equals() { diff --git a/android/README.md b/android/README.md deleted file mode 100644 index ef274b1b07..0000000000 --- a/android/README.md +++ /dev/null @@ -1,51 +0,0 @@ - -## Android Port of Foundation module - -This directory contains scripts used in the port of Foundation to -an Android toolchain. The short version of the story is that after -downloading the swift sources use the script "prepare.sh" in this -directory to install prebuilt binaries and headers for libxml, -libcurl and libdispatch then run the script "builder.sh". - -This build requires the path to a [r12 Android NDK](http://developer.android.com/ndk/downloads/index.html) in the -`ANDROID_NDK_HOME` environment variable and the path to the -android port of the "icu" libraries in `ANDROID_ICU_UC` -downloaded from [here](https://github.com/SwiftAndroid/libiconv-libicu-android/releases/download/android-ndk-r12/libiconv-libicu-armeabi-v7a-ubuntu-15.10-ndk-r12.tar.gz). -The port was tested against api 21 on a Android v5.1.1 LG K4 Phone (Lollipop) -and requires an Ubuntu 15 host with the Android NDK Gold linker from -`toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin` installed as /usr/bin/ld.gold. - -The pre-built binaries were built from the following repos: - -[https://github.com/curl/curl](https://github.com/curl/curl) - -[https://github.com/android/platform_external_libxml2](https://github.com/android/platform_external_libxml2) - -[https://github.com/apple/swift-corelibs-libdispatch](https://github.com/apple/swift-corelibs-libdispatch) - -[https://github.com/mheily/libpwq](https://github.com/mheily/libpwq) - -[https://github.com/mheily/libkqueue](https://github.com/mheily/libkqueue) - -To build these the recipe was generally the same. autogen or configure -for Linux then alter their Makefiles to have CFLAGS = include: --target=armv7-none-linux-androideabi --sysroot=$(ANDROID_NDK_HOME)/platforms/android-21/arch-arm. - -There is a known issue when libdispatch background tasks exit -they will cause an exception as DetachCurrentThread has not -been called. To avoid this your app must include the line: - - DispatchGroup.threadCleanupCallback = JNI_DetachCurrentThread - -JNI_DetachCurrentThread is available in the package java_swift -available here: https://github.com/SwiftJava/java_swift - -Pre-built binaries of an Swift compiler with support for Android -including Foundation available here: - -http://johnholdsworth.com/android_toolchain.tgz - -### Other resources - -Check out the [SwiftAndroid](https://github.com/SwiftAndroid) and -[SwiftJava](https://github.com/SwiftJava) github projects for -starter Android applications and resources. diff --git a/android/builder.sh b/android/builder.sh deleted file mode 100755 index d00b8dad50..0000000000 --- a/android/builder.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -x -# -# Build Android toolchain including Foundation -# - -cd "$(dirname $0)" && -#./prepare.sh && -./install.sh -u && - -pushd "../../swift" && -./utils/build-script \ - -R --skip-build-libdispatch --foundation \ - --android \ - --android-ndk "${ANDROID_NDK_HOME:?Please set ANDROID_NDK_HOME to path to an Android NDK downloaded from http://developer.android.com/ndk/downloads/index.html}" \ - --android-api-level 21 \ - --android-icu-uc "${ANDROID_ICU_UC:?Please set ANDROID_ICU_UC to path to Android ICU downloaded from https://github.com/SwiftAndroid/libiconv-libicu-android/releases/download/android-ndk-r12/libiconv-libicu-armeabi-v7a-ubuntu-15.10-ndk-r12.tar.gz}/armeabi-v7a" \ - --android-icu-uc-include "${ANDROID_ICU_UC}/armeabi-v7a/icu/source/common" \ - --android-icu-i18n "${ANDROID_ICU_UC}/armeabi-v7a" \ - --android-icu-i18n-include "${ANDROID_ICU_UC}/armeabi-v7a/icu/source/i18n" && - -popd && ./install.sh diff --git a/android/install.sh b/android/install.sh deleted file mode 100755 index c724695771..0000000000 --- a/android/install.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# Simple script to move Android Foundation into toolchain -# To build it again after this, use install.sh -u to reset -# - -cd "$(dirname $0)" - -SWIFT_ROOT="$(dirname $(dirname $(which swiftc)))" -BUILD_DIR="$(dirname $SWIFT_ROOT)" - -if [[ "$1" == "-u" ]]; then - rm -rf "${SWIFT_ROOT}/lib/swift/CoreFoundation" - exit -fi - -\cp -v "${BUILD_DIR}/foundation-linux-x86_64/Foundation/libFoundation.so" "${SWIFT_ROOT}/lib/swift/android" && - -\cp -v "${BUILD_DIR}/foundation-linux-x86_64/Foundation/Foundation.swift"* "${SWIFT_ROOT}/lib/swift/android/armv7" && - -rsync -arv "${BUILD_DIR}/foundation-linux-x86_64/Foundation/usr/lib/swift/CoreFoundation" "${SWIFT_ROOT}/lib/swift/" diff --git a/android/package.sh b/android/package.sh deleted file mode 100755 index 4657c49ca1..0000000000 --- a/android/package.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# -# Prepare binary package used to build Foundation for Android -# - -cd "$(dirname $0)" && -TAR_FILE="$(pwd)/android_dispatch" && - -cd "../../platform_external_libxml2/include" && -tar cf "$TAR_FILE.tar" libxml && - -cd "../../curl/include" && -tar rf "$TAR_FILE.tar" curl && - -cd "$(dirname $(dirname $(which swiftc)))/lib/swift" && - -tar rf "$TAR_FILE.tar" dispatch android/lib{xml2,curl,dispatch}.so android/armv7/Dispatch.swift* && - -gzip "$TAR_FILE.tar" && -\mv "$TAR_FILE.tar.gz" "$TAR_FILE.tgz" && - -tar tfvz "$TAR_FILE.tgz" diff --git a/android/prepare.sh b/android/prepare.sh deleted file mode 100755 index 5e3ce2d7d2..0000000000 --- a/android/prepare.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# Prepare swift sourcerelease to build Foundation for Android -# - -BUILD_DIR="build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift" - -cd "$(dirname $0)" && -TAR_FILE="$(pwd)/android_dispatch.tgz" && - -if [[ ! -f "${TAR_FILE}" ]]; then - echo "Fetching binaries and headers for libxml2, libcurl and libdispatch" - curl "https://raw.githubusercontent.com/SwiftJava/SwiftJava/master/android_dispatch.tgz" > "${TAR_FILE}" -fi - -cd "../.." && mkdir -p "${BUILD_DIR}" && -cd "${BUILD_DIR}" && tar xfvz "${TAR_FILE}" diff --git a/android/updater.sh b/android/updater.sh deleted file mode 100755 index 1dcd2c7107..0000000000 --- a/android/updater.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# -# Move freshly built dependencies for Foundation into -# build directory to be available for it's compilation. -# -# libxml2.so built from the android platform port: -# https://github.com/android/platform_external_libxml2 -# -# This is the most useful page found but it's not complete -# http://stackoverflow.com/questions/12052089/using-libxml-for-android -# Don't set CFLAGS or LDFLAGS and use ./autogen.sh instead of "configure" -# Remove HTMLparser.lo and HTMLtree.lo from the Makefile and make sure -# LIBXML_HTML_ENABLED and LIBXML_ICONV_ENABLED were not enabled in file -# "include/libxml/xmlversion.h". Add the following to CFLAGS in Makefile: -# -nostdlib --target=armv7-none-linux-androideabi -# --sysroot=$ANDROID_NDK/platforms/android-21/arch-arm -# -# libcurl.so is built similarly from https://github.com/curl/curl -# -# libdispatch.so is a difficult build soon to be automated by another PR. -# - -ANDROID_ICU_UC="${ANDROID_ICU_UC:-$HOME/libiconv-libicu-android}" - -cd "$(dirname $0)" && - -SWIFT_ROOT="$(dirname $(dirname $(which swiftc)))" && -BUILD_DIR="$(dirname $SWIFT_ROOT)" && - -\cp -v ../../platform_external_libxml2/libxml2.so ../../curl/libcurl.so ../../swift-corelibs-libdispatch/libdispatch.so "$ANDROID_ICU_UC"/armeabi-v7a/libicu*.so "${SWIFT_ROOT}/lib/swift/android" && - -\cp -v "${BUILD_DIR}/libdispatch-linux-x86_64/src/swift/Dispatch.swift"* "${SWIFT_ROOT}/lib/swift/android/armv7" && - -rsync -arv "../../swift-corelibs-libdispatch/dispatch" "${SWIFT_ROOT}/lib/swift/" && - -\cp -v "../../swift-corelibs-libdispatch/private/"*.h "${SWIFT_ROOT}/lib/swift/dispatch" && - -rpl -R -e libicu libscu "${SWIFT_ROOT}/lib/swift/android"/lib{icu,swift,Foundation,xml2}*.so && - -for i in "${SWIFT_ROOT}/lib/swift/android"/libicu*.so; do \mv -f $i ${i/libicu/libscu}; done