Merge pull request #162 from gonzalolarralde/android-support
Android support
diff --git a/Makefile.am b/Makefile.am
index cdc642f..63c8b17 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,6 +12,10 @@
MAYBE_KQUEUES = libkqueue
endif
+if BUILD_TESTS
+ MAYBE_TESTS = tests
+endif
+
SUBDIRS= \
dispatch \
$(MAYBE_PTHREAD_WORKQUEUES) \
@@ -20,7 +24,7 @@
os \
private \
src \
- tests
+ $(MAYBE_TESTS)
EXTRA_DIST= \
README.md \
diff --git a/configure.ac b/configure.ac
index b923c66..98e1142 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11,6 +11,10 @@
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
@@ -57,6 +61,53 @@
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 @@
[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 @@
)
AM_CONDITIONAL(HAVE_SWIFT, $have_swift)
AC_SUBST([SWIFTC])
+AC_SUBST([SWIFTC_FLAGS])
AC_SUBST([SWIFT_LIBDIR])
#
@@ -474,6 +524,13 @@
)
#
+# 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.
#
AC_CONFIG_FILES([Makefile dispatch/Makefile man/Makefile os/Makefile private/Makefile src/Makefile tests/Makefile])
diff --git a/src/Makefile.am b/src/Makefile.am
index eaabce4..967d5a0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,6 +41,7 @@
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_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 @@
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 4408d96..8934b2c 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 <pthread.h>
#include "os/object_private.h"
#include "queue_private.h"
#include "source_private.h"
@@ -245,7 +246,11 @@
#include <sys/event.h>
#include <sys/mount.h>
#include <sys/queue.h>
+#ifdef __ANDROID__
+#include <linux/sysctl.h>
+#else
#include <sys/sysctl.h>
+#endif /* __ANDROID__ */
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/mman.h>
diff --git a/src/queue.c b/src/queue.c
index 0c058be..86018fd 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -976,6 +976,7 @@
#include <unistd.h>
#include <sys/syscall.h>
+#ifndef __ANDROID__
#ifdef SYS_gettid
DISPATCH_ALWAYS_INLINE
static inline pid_t
@@ -985,7 +986,8 @@
}
#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 db28822..30d8929 100644
--- a/src/shims.h
+++ b/src/shims.h
@@ -97,6 +97,10 @@
#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 0000000..934552d
--- /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 74aba13..0aafaef 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 07ee8bc..4923eb0 100644
--- a/src/shims/linux_stubs.c
+++ b/src/shims/linux_stubs.c
@@ -17,7 +17,11 @@
*/
#include <stdint.h>
+#ifdef __ANDROID__
+#include <sys/syscall.h>
+#else
#include <syscall.h>
+#endif /* __ANDROID__ */
#if __has_include(<config/config_ac.h>)
#include <config/config_ac.h>
diff --git a/src/shims/linux_stubs.h b/src/shims/linux_stubs.h
index 0c12e82..8bdf3ff 100644
--- a/src/shims/linux_stubs.h
+++ b/src/shims/linux_stubs.h
@@ -71,7 +71,9 @@
#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 2fab691..983fe47 100644
--- a/src/shims/lock.c
+++ b/src/shims/lock.c
@@ -117,7 +117,11 @@
#pragma mark - futex wrappers
#if HAVE_FUTEX
#include <sys/time.h>
+#ifdef __ANDROID__
+#include <sys/syscall.h>
+#else
#include <syscall.h>
+#endif /* __ANDROID__ */
DISPATCH_ALWAYS_INLINE
static inline int
diff --git a/src/source.c b/src/source.c
index afb811c..7537f32 100644
--- a/src/source.c
+++ b/src/source.c
@@ -2034,8 +2034,10 @@
};
#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 9dab8f0..801ae71 100644
--- a/src/swift/Source.swift
+++ b/src/swift/Source.swift
@@ -112,7 +112,7 @@
}
#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 @@
}
#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 @@
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 @@
}
#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 @@
}
}
-#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_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 @@
@_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 deb3c6d..34ccc1b 100644
--- a/src/swift/Wrapper.swift
+++ b/src/swift/Wrapper.swift
@@ -180,7 +180,7 @@
}
#endif
-#if !os(Linux)
+#if !os(Linux) && !os(Android)
extension DispatchSource : DispatchSourceProcess,
DispatchSourceFileSystemObject {
}
@@ -268,7 +268,7 @@
}
#endif
-#if !os(Linux)
+#if !os(Linux) && !os(Android)
public protocol DispatchSourceProcess : DispatchSourceProtocol {
var handle: pid_t { get }
@@ -298,7 +298,7 @@
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 613dbb4..c516366 100644
--- a/tests/Foundation/bench.mm
+++ b/tests/Foundation/bench.mm
@@ -20,7 +20,11 @@
#include <Foundation/Foundation.h>
#include <libkern/OSAtomic.h>
+#ifdef __ANDROID__
+#include <linux/sysctl.h>
+#else
#include <sys/sysctl.h>
+#endif /* __ANDROID__ */
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <stdio.h>
diff --git a/tests/dispatch_apply.c b/tests/dispatch_apply.c
index ff71fad..85bdf80 100644
--- a/tests/dispatch_apply.c
+++ b/tests/dispatch_apply.c
@@ -27,7 +27,11 @@
#include <libkern/OSAtomic.h>
#endif
#include <sys/types.h>
+#ifdef __ANDROID__
+#include <linux/sysctl.h>
+#else
#include <sys/sysctl.h>
+#endif /* __ANDROID__ */
#include <bsdtests.h>
#include "dispatch_test.h"
diff --git a/tests/dispatch_concur.c b/tests/dispatch_concur.c
index ffd42c0..ac62292 100644
--- a/tests/dispatch_concur.c
+++ b/tests/dispatch_concur.c
@@ -24,7 +24,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
+#ifdef __ANDROID__
+#include <linux/sysctl.h>
+#else
#include <sys/sysctl.h>
+#endif /* __ANDROID__ */
#include <bsdtests.h>
#include "dispatch_test.h"
diff --git a/tests/dispatch_priority.c b/tests/dispatch_priority.c
index 590414e..3cbb7d9 100644
--- a/tests/dispatch_priority.c
+++ b/tests/dispatch_priority.c
@@ -28,7 +28,11 @@
#include <TargetConditionals.h>
#endif
#include <sys/types.h>
+#ifdef __ANDROID__
+#include <linux/sysctl.h>
+#else
#include <sys/sysctl.h>
+#endif /* __ANDROID__ */
#include <bsdtests.h>
#include "dispatch_test.h"
diff --git a/tests/dispatch_readsync.c b/tests/dispatch_readsync.c
index aaec909..207e60f 100644
--- a/tests/dispatch_readsync.c
+++ b/tests/dispatch_readsync.c
@@ -22,7 +22,11 @@
#include <dispatch/private.h>
#include <stdlib.h>
#include <unistd.h>
+#ifdef __ANDROID__
+#include <linux/sysctl.h>
+#else
#include <sys/sysctl.h>
+#endif /* __ANDROID__ */
#include <assert.h>
#include <bsdtests.h>
diff --git a/tests/dispatch_vm.c b/tests/dispatch_vm.c
index f246acf..6877411 100644
--- a/tests/dispatch_vm.c
+++ b/tests/dispatch_vm.c
@@ -26,7 +26,11 @@
#include <libkern/OSAtomic.h>
#endif
#include <assert.h>
+#ifdef __ANDROID__
+#include <linux/sysctl.h>
+#else
#include <sys/sysctl.h>
+#endif /* __ANDROID__ */
#include <stdarg.h>
#include <time.h>