diff --git a/Makefile.am b/Makefile.am index cdc642f4d..63c8b17aa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,6 +12,10 @@ if BUILD_OWN_KQUEUES MAYBE_KQUEUES = libkqueue endif +if BUILD_TESTS + MAYBE_TESTS = tests +endif + SUBDIRS= \ dispatch \ $(MAYBE_PTHREAD_WORKQUEUES) \ @@ -20,7 +24,7 @@ SUBDIRS= \ os \ private \ src \ - tests + $(MAYBE_TESTS) EXTRA_DIST= \ README.md \ diff --git a/configure.ac b/configure.ac index b923c6653..98e114209 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,10 @@ AC_CONFIG_MACRO_DIR([m4]) ac_clean_files=a.out.dSYM AM_MAINTAINER_MODE +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + # # Command line argument to specify build variant (default to release). # Impacts default value of CFLAGS et al. so must come before AC_PROG_CC @@ -56,6 +60,53 @@ AC_PROG_CXX([clang++ g++ c++]) AC_PROG_OBJC([clang gcc cc]) AC_PROG_OBJCXX([clang++ g++ c++]) +# +# Android cross-compilation support +# +AC_ARG_WITH([android-ndk], + [AS_HELP_STRING([--with-android-ndk], + [Android NDK location])], [ + android_ndk=${withval} +]) +AC_ARG_WITH([android-ndk-gcc-version], + [AS_HELP_STRING([--with-android-ndk-gcc-version], + [Android NDK GCC version [defaults=4.9]])], + [android_ndk_gcc_version=${withval}], [android_ndk_gcc_version=4.9]) +AC_ARG_WITH([android-api-level], + [AS_HELP_STRING([--with-android-api-level], + [Android API level to link with])], [ + android_api_level=${withval} +]) +AC_ARG_ENABLE([android], + [AS_HELP_STRING([--enable-android], + [Compile for Android])], [ + android=true + + # Override values until there's real support for multiple Android platforms + host=armv7-none-linux-androideabi + host_alias=arm-linux-androideabi + host_cpu=armv7 + host_os=linux-androideabi + host_vendor=unknown + arch=arm + + sysroot=${android_ndk}/platforms/android-${android_api_level}/arch-${arch} + toolchain=${android_ndk}/toolchains/${host_alias}-${android_ndk_gcc_version}/prebuilt/linux-${build_cpu} + + CFLAGS="$CFLAGS -target ${host_alias} --sysroot=${sysroot} -B${toolchain}/${host_alias}/bin" + CXXFLAGS="$CXXFLAGS -target ${host_alias} --sysroot=${sysroot} -B${toolchain}/${host_alias}/bin" + SWIFTC_FLAGS="-target ${host} -sdk ${sysroot} -L${toolchain}/lib/gcc/${host_alias}/${android_ndk_gcc_version}.x" + LIBS="$LIBS -L${toolchain}/lib/gcc/${host_alias}/${android_ndk_gcc_version}.x" + LDFLAGS="$LDFLAGS -Wc,'-target','${host_alias}','-B${toolchain}/${host_alias}/bin'" + + # FIXME: empty CFLAGS and CXXFLAGS are assumed for this to work. + # FIXME: there should be a more elegant way to do this + ac_configure_args=`echo $ac_configure_args | sed -e "s/ 'CFLAGS='//" -e "s/ 'CXXFLAGS='//"` + # CFLAGS, CXXFLAGS and LIBS needs to be passed to libkqueue and libpwq + ac_configure_args="$ac_configure_args --enable-bionic-libc 'CFLAGS=$CFLAGS' 'CXXFLAGS=$CXXFLAGS' 'LIBS=$LIBS'" +], [android=false]) +AM_CONDITIONAL(ANDROID, $android) + # # On Mac OS X, some required header files come from other source packages; # allow specifying where those are. @@ -134,8 +185,6 @@ AS_IF([test "x$enable_apple_tsd_optimizations" = "xyes"], [Define to use non-portable pthread TSD optimizations for Mac OS X)])] ) -AC_CANONICAL_TARGET - # # Enable building Swift overlay support into libdispatch # @@ -164,6 +213,7 @@ AC_ARG_WITH([swift-toolchain], ) AM_CONDITIONAL(HAVE_SWIFT, $have_swift) AC_SUBST([SWIFTC]) +AC_SUBST([SWIFTC_FLAGS]) AC_SUBST([SWIFT_LIBDIR]) # @@ -473,6 +523,13 @@ AC_COMPILE_IFELSE( [AC_DEFINE(HAVE_NORETURN_BUILTIN_TRAP, 1, [Define if __builtin_trap marked noreturn])] ) +# +# Add option to avoid building tests +# +AC_ARG_ENABLE([build-tests], + [AS_HELP_STRING([--disable-build-tests], [Disable tests compilation])]) +AM_CONDITIONAL(BUILD_TESTS, [test "x$enable_build_tests" != "xno"]) + # # Generate Makefiles. # diff --git a/src/Makefile.am b/src/Makefile.am index eaabce4d6..967d5a073 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,7 @@ libdispatch_la_SOURCES= \ trace.h \ voucher_internal.h \ firehose/firehose_internal.h \ + shims/android_stubs.h \ shims/atomic.h \ shims/atomic_sfb.h \ shims/getprogname.h \ @@ -148,7 +149,7 @@ SWIFT_SRC_FILES=\ SWIFT_ABS_SRC_FILES = $(SWIFT_SRC_FILES:%=$(abs_srcdir)/%) SWIFT_OBJ_FILES = $(abs_builddir)/swift/swift_overlay.o -SWIFTC_FLAGS = -Xcc -fmodule-map-file=$(abs_top_srcdir)/dispatch/module.modulemap -I$(abs_top_srcdir) -Xcc -fblocks +SWIFTC_FLAGS+= -Xcc -fmodule-map-file=$(abs_top_srcdir)/dispatch/module.modulemap -I$(abs_top_srcdir) -Xcc -fblocks if DISPATCH_ENABLE_OPTIMIZATION SWIFTC_FLAGS+=-O endif @@ -180,4 +181,3 @@ BUILT_SOURCES=$(MIG_SOURCES) $(DTRACE_SOURCES) nodist_libdispatch_la_SOURCES=$(BUILT_SOURCES) CLEANFILES=$(BUILT_SOURCES) $(SWIFT_GEN_FILES) DISTCLEANFILES=pthread_machdep.h pthread System mach objc - diff --git a/src/internal.h b/src/internal.h index 4408d9672..8934b2cb5 100644 --- a/src/internal.h +++ b/src/internal.h @@ -155,6 +155,7 @@ #endif /* private.h must be included last to avoid picking up installed headers. */ +#include #include "os/object_private.h" #include "queue_private.h" #include "source_private.h" @@ -245,7 +246,11 @@ DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_child(void); #include #include #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #include #include #include diff --git a/src/queue.c b/src/queue.c index 0c058be55..86018fde9 100644 --- a/src/queue.c +++ b/src/queue.c @@ -976,6 +976,7 @@ _dispatch_get_mach_host_port(void) #include #include +#ifndef __ANDROID__ #ifdef SYS_gettid DISPATCH_ALWAYS_INLINE static inline pid_t @@ -985,7 +986,8 @@ gettid(void) } #else #error "SYS_gettid unavailable on this system" -#endif +#endif /* SYS_gettid */ +#endif /* ! __ANDROID__ */ #define _tsd_call_cleanup(k, f) do { \ if ((f) && tsd->k) ((void(*)(void*))(f))(tsd->k); \ diff --git a/src/shims.h b/src/shims.h index db288225e..30d8929d4 100644 --- a/src/shims.h +++ b/src/shims.h @@ -97,6 +97,10 @@ typedef unsigned long pthread_priority_t; #include "shims/linux_stubs.h" #endif +#ifdef __ANDROID__ +#include "shims/android_stubs.h" +#endif + typedef uint32_t dispatch_priority_t; #define DISPATCH_SATURATED_OVERRIDE ((dispatch_priority_t)UINT32_MAX) diff --git a/src/shims/android_stubs.h b/src/shims/android_stubs.h new file mode 100644 index 000000000..934552d51 --- /dev/null +++ b/src/shims/android_stubs.h @@ -0,0 +1,34 @@ +/* + * This source file is part of the Swift.org open source project + * + * Copyright (c) 2015 Apple Inc. and the Swift project authors + * + * Licensed under Apache License v2.0 with Runtime Library Exception + * + * See http://swift.org/LICENSE.txt for license information + * See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + * + */ + +// forward declarations for functions we are stubbing out +// in the intial android port. + +#ifndef __DISPATCH__ANDROID__STUBS__INTERNAL +#define __DISPATCH__ANDROID__STUBS__INTERNAL + +/* + * Missing sys/queue.h macro stubs + */ + +#ifndef TAILQ_FOREACH_SAFE +# define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif /* TAILQ_FOREACH_SAFE */ + +#ifndef TRASHIT +# define TRASHIT(x) do {(x) = (void *)-1;} while (0) +#endif /* TRASHIT */ + +#endif /* __DISPATCH__ANDROID__STUBS__INTERNAL */ \ No newline at end of file diff --git a/src/shims/getprogname.h b/src/shims/getprogname.h index 74aba1318..0aafaef4e 100644 --- a/src/shims/getprogname.h +++ b/src/shims/getprogname.h @@ -23,11 +23,18 @@ #define __DISPATCH_SHIMS_GETPROGNAME__ #if !HAVE_GETPROGNAME + +#ifdef __ANDROID__ +extern const char *__progname; +#endif /* __ANDROID */) + static inline char * getprogname(void) { # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME return program_invocation_short_name; +# elif defined(__ANDROID__) + return __progname; # else # error getprogname(3) is not available on this platform # endif diff --git a/src/shims/linux_stubs.c b/src/shims/linux_stubs.c index 07ee8bc06..4923eb0ca 100644 --- a/src/shims/linux_stubs.c +++ b/src/shims/linux_stubs.c @@ -17,7 +17,11 @@ */ #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #if __has_include() #include diff --git a/src/shims/linux_stubs.h b/src/shims/linux_stubs.h index 0c12e8272..8bdf3ff0e 100644 --- a/src/shims/linux_stubs.h +++ b/src/shims/linux_stubs.h @@ -71,7 +71,9 @@ typedef void (*dispatch_mach_msg_destructor_t)(void*); #endif // SIZE_T_MAX should not be hardcoded like this here. -#define SIZE_T_MAX (0x7fffffff) +#ifndef SIZE_T_MAX +#define SIZE_T_MAX (~(size_t)0) +#endif // Define to 0 the NOTE_ values that are not present on Linux. // Revisit this...would it be better to ifdef out the uses instead?? diff --git a/src/shims/lock.c b/src/shims/lock.c index 2fab69107..983fe47b3 100644 --- a/src/shims/lock.c +++ b/src/shims/lock.c @@ -117,7 +117,11 @@ _dispatch_unfair_lock_wake(uint32_t *uaddr, uint32_t flags) #pragma mark - futex wrappers #if HAVE_FUTEX #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ DISPATCH_ALWAYS_INLINE static inline int diff --git a/src/source.c b/src/source.c index afb811c40..7537f3223 100644 --- a/src/source.c +++ b/src/source.c @@ -2034,8 +2034,10 @@ _dispatch_kevent_qos_s _dispatch_kevent_timeout[] = { }; #define DISPATCH_KEVENT_TIMEOUT_COUNT \ ((sizeof(_dispatch_kevent_timeout) / sizeof(_dispatch_kevent_timeout[0]))) -static_assert(DISPATCH_KEVENT_TIMEOUT_COUNT == DISPATCH_TIMER_INDEX_COUNT - 1, +#if __has_feature(c_static_assert) +_Static_assert(DISPATCH_KEVENT_TIMEOUT_COUNT == DISPATCH_TIMER_INDEX_COUNT - 1, "should have a kevent for everything but disarm (ddt assumes this)"); +#endif #define DISPATCH_KEVENT_COALESCING_WINDOW_INIT(qos, ms) \ [DISPATCH_TIMER_QOS_##qos] = 2ull * (ms) * NSEC_PER_MSEC diff --git a/src/swift/Source.swift b/src/swift/Source.swift index 9dab8f0a9..801ae71e3 100644 --- a/src/swift/Source.swift +++ b/src/swift/Source.swift @@ -112,7 +112,7 @@ public extension DispatchSource { } #endif -#if !os(Linux) +#if !os(Linux) && !os(Android) public struct ProcessEvent : OptionSet, RawRepresentable { public let rawValue: UInt public init(rawValue: UInt) { self.rawValue = rawValue } @@ -170,7 +170,7 @@ public extension DispatchSource { } #endif -#if !os(Linux) +#if !os(Linux) && !os(Android) public class func makeProcessSource(identifier: pid_t, eventMask: ProcessEvent, queue: DispatchQueue? = nil) -> DispatchSourceProcess { let source = dispatch_source_create(_swift_dispatch_source_type_proc(), UInt(identifier), eventMask.rawValue, queue?.__wrapped) return DispatchSource(source: source) as DispatchSourceProcess @@ -202,7 +202,7 @@ public extension DispatchSource { return DispatchSource(source: source) as DispatchSourceUserDataOr } -#if !os(Linux) +#if !os(Linux) && !os(Android) public class func makeFileSystemObjectSource(fileDescriptor: Int32, eventMask: FileSystemEvent, queue: DispatchQueue? = nil) -> DispatchSourceFileSystemObject { let source = dispatch_source_create(_swift_dispatch_source_type_vnode(), UInt(fileDescriptor), eventMask.rawValue, queue?.__wrapped) return DispatchSource(source: source) as DispatchSourceFileSystemObject @@ -255,7 +255,7 @@ public extension DispatchSourceMemoryPressure { } #endif -#if !os(Linux) +#if !os(Linux) && !os(Android) public extension DispatchSourceProcess { public var handle: pid_t { return pid_t(dispatch_source_get_handle(self as! DispatchSource)) @@ -299,7 +299,7 @@ public extension DispatchSourceTimer { } } -#if !os(Linux) +#if !os(Linux) && !os(Android) public extension DispatchSourceFileSystemObject { public var handle: Int32 { return Int32(dispatch_source_get_handle((self as! DispatchSource).__wrapped)) @@ -368,7 +368,7 @@ internal func _swift_dispatch_source_type_mach_recv() -> dispatch_source_type_t internal func _swift_dispatch_source_type_memorypressure() -> dispatch_source_type_t #endif -#if !os(Linux) +#if !os(Linux) && !os(Android) @_silgen_name("_swift_dispatch_source_type_PROC") internal func _swift_dispatch_source_type_proc() -> dispatch_source_type_t #endif @@ -382,7 +382,7 @@ internal func _swift_dispatch_source_type_signal() -> dispatch_source_type_t @_silgen_name("_swift_dispatch_source_type_TIMER") internal func _swift_dispatch_source_type_timer() -> dispatch_source_type_t -#if !os(Linux) +#if !os(Linux) && !os(Android) @_silgen_name("_swift_dispatch_source_type_VNODE") internal func _swift_dispatch_source_type_vnode() -> dispatch_source_type_t #endif diff --git a/src/swift/Wrapper.swift b/src/swift/Wrapper.swift index deb3c6dfe..34ccc1b1f 100644 --- a/src/swift/Wrapper.swift +++ b/src/swift/Wrapper.swift @@ -180,7 +180,7 @@ extension DispatchSource : DispatchSourceMachSend, } #endif -#if !os(Linux) +#if !os(Linux) && !os(Android) extension DispatchSource : DispatchSourceProcess, DispatchSourceFileSystemObject { } @@ -268,7 +268,7 @@ public protocol DispatchSourceMemoryPressure : DispatchSourceProtocol { } #endif -#if !os(Linux) +#if !os(Linux) && !os(Android) public protocol DispatchSourceProcess : DispatchSourceProtocol { var handle: pid_t { get } @@ -298,7 +298,7 @@ public protocol DispatchSourceTimer : DispatchSourceProtocol { func scheduleRepeating(wallDeadline: DispatchWallTime, interval: Double, leeway: DispatchTimeInterval) } -#if !os(Linux) +#if !os(Linux) && !os(Android) public protocol DispatchSourceFileSystemObject : DispatchSourceProtocol { var handle: Int32 { get } diff --git a/tests/Foundation/bench.mm b/tests/Foundation/bench.mm index 613dbb4b2..c516366f7 100644 --- a/tests/Foundation/bench.mm +++ b/tests/Foundation/bench.mm @@ -20,7 +20,11 @@ #include #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #include #include #include diff --git a/tests/dispatch_apply.c b/tests/dispatch_apply.c index ff71fada1..85bdf80ee 100644 --- a/tests/dispatch_apply.c +++ b/tests/dispatch_apply.c @@ -27,7 +27,11 @@ #include #endif #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #include #include "dispatch_test.h" diff --git a/tests/dispatch_concur.c b/tests/dispatch_concur.c index ffd42c0ab..ac6229280 100644 --- a/tests/dispatch_concur.c +++ b/tests/dispatch_concur.c @@ -24,7 +24,11 @@ #include #include #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #include #include "dispatch_test.h" diff --git a/tests/dispatch_priority.c b/tests/dispatch_priority.c index 590414e64..3cbb7d979 100644 --- a/tests/dispatch_priority.c +++ b/tests/dispatch_priority.c @@ -28,7 +28,11 @@ #include #endif #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #include #include "dispatch_test.h" diff --git a/tests/dispatch_readsync.c b/tests/dispatch_readsync.c index aaec9093f..207e60f26 100644 --- a/tests/dispatch_readsync.c +++ b/tests/dispatch_readsync.c @@ -22,7 +22,11 @@ #include #include #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #include #include diff --git a/tests/dispatch_vm.c b/tests/dispatch_vm.c index f246acf86..68774111d 100644 --- a/tests/dispatch_vm.c +++ b/tests/dispatch_vm.c @@ -26,7 +26,11 @@ #include #endif #include +#ifdef __ANDROID__ +#include +#else #include +#endif /* __ANDROID__ */ #include #include