~ chicken-core (chicken-5) d152736aac8dcb9b3d5a5dd0254351ad32e1d9c6
commit d152736aac8dcb9b3d5a5dd0254351ad32e1d9c6
Author: felix <address@hidden>
AuthorDate: Wed Dec 18 14:36:16 2013 +0100
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Mon Jan 20 15:35:38 2014 +0100
Added Android-specific changes to posix-unit and runtime and added a simple makefile.
Signed-off-by: Peter Bex <address@hidden>
Signed-off-by: felix <felix@call-with-current-continuation.org>
diff --git a/Makefile.android b/Makefile.android
new file mode 100644
index 00000000..7aafbd50
--- /dev/null
+++ b/Makefile.android
@@ -0,0 +1,108 @@
+# Makefile.android - configuration for Android -*- Makefile -*-
+#
+# Copyright (c) 2013, The Chicken Team
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
+# conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+# disclaimer.
+# Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the distribution.
+# Neither the name of the author nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+
+ifneq ($(CONFIG),)
+include $(CONFIG)
+endif
+
+SRCDIR ?= ./
+
+# platform configuration
+
+ARCH ?= $(shell sh $(SRCDIR)/config-arch.sh)
+
+# options
+
+C_COMPILER_OPTIONS ?= -fno-strict-aliasing -fwrapv -DHAVE_CHICKEN_CONFIG_H
+ifdef DEBUGBUILD
+C_COMPILER_OPTIMIZATION_OPTIONS ?= -g -Wall -Wno-unused
+else
+ifdef OPTIMIZE_FOR_SPEED
+C_COMPILER_OPTIMIZATION_OPTIONS ?= -O3 -fomit-frame-pointer
+else
+C_COMPILER_OPTIMIZATION_OPTIONS ?= -Os -fomit-frame-pointer
+endif
+endif
+LINKER_LINK_SHARED_LIBRARY_OPTIONS = -shared
+LINKER_LINK_SHARED_DLOADABLE_OPTIONS = -L. -shared -Wl,-R"$(RUNTIME_LINKER_PATH)"
+LINKER_LINK_SHARED_PROGRAM_OPTIONS = -Wl,-R"$(RUNTIME_LINKER_PATH)"
+# Android NDK build system currently does not understand
+# versioned sonames, so don't try to embed a soname.
+#LIBCHICKEN_SO_LINKER_OPTIONS = -Wl,-soname,lib$(PROGRAM_PREFIX)chicken$(PROGRAM_SUFFIX).so.$(BINARYVERSION)
+LIBRARIES = -lm -ldl -llog
+NEEDS_RELINKING = yes
+# See above
+#USES_SONAME = yes
+
+# special files
+
+CHICKEN_CONFIG_H = chicken-config.h
+
+# select default and internal settings
+
+include $(SRCDIR)/defaults.make
+
+chicken-config.h: chicken-defaults.h
+ echo "/* GENERATED */" >$@
+ echo "#define HAVE_DIRENT_H 1" >>$@
+ echo "#define HAVE_DLFCN_H 1" >>$@
+ echo "#define HAVE_INTTYPES_H 1" >>$@
+ echo "#define HAVE_LIMITS_H 1" >>$@
+ echo "#define HAVE_LONG_LONG 1" >>$@
+ echo "#define HAVE_MEMMOVE 1" >>$@
+ echo "#define HAVE_MEMORY_H 1" >>$@
+ echo "#define HAVE_SIGACTION 1" >>$@
+ echo "#define HAVE_SIGSETJMP 1" >>$@
+ echo "#define HAVE_STDINT_H 1" >>$@
+ echo "#define HAVE_STDLIB_H 1" >>$@
+ echo "#define HAVE_STRERROR 1" >>$@
+ echo "#define HAVE_STRINGS_H 1" >>$@
+ echo "#define HAVE_STRING_H 1" >>$@
+ echo "#define HAVE_STRTOLL 1" >>$@
+ echo "#define HAVE_STRTOQ 1" >>$@
+ echo "#define HAVE_SYS_STAT_H 1" >>$@
+ echo "#define HAVE_SYS_TYPES_H 1" >>$@
+ echo "#define HAVE_UNISTD_H 1" >>$@
+ echo "#define HAVE_UNSIGNED_LONG_LONG 1" >>$@
+ echo "#define STDC_HEADERS 1" >>$@
+ echo "#define HAVE_ALLOCA 1" >>$@
+ echo "#define HAVE_ALLOCA_H 1" >>$@
+ echo "#define HAVE_GRP_H 1" >>$@
+ echo "#define HAVE_ERRNO_H 1" >>$@
+ echo "#define HAVE_MEMMOVE 1" >>$@
+ echo "#define C_STACK_GROWS_DOWNWARD 1" >>$@
+ifdef GCHOOKS
+ echo "#define C_GC_HOOKS" >>$@
+endif
+ifdef SYMBOLGC
+ echo "#define C_COLLECT_ALL_SYMBOLS" >>$@
+endif
+ifneq ($(HACKED_APPLY),)
+ echo "#define C_HACKED_APPLY" >>$@
+endif
+ cat chicken-defaults.h >>$@
+
+include $(SRCDIR)/rules.make
diff --git a/README b/README
index 82781122..bb3a1060 100644
--- a/README
+++ b/README
@@ -359,6 +359,30 @@
5. Platform issues
+ Android:
+
+ - The Android SDK and NDK are required. Make sure you have
+ set up a project and have a suitable NDK toolchain
+ available. You will have to override the make(1) variable
+ C_COMPILER to contain the correct compiler; see
+ docs/STANDALONE-TOOLCHAIN.html in your NDK root for notes
+ on how to call the correct compiler. You will also need to
+ override the ARCH variable to match the device you're
+ targeting. The build will produce a libchicken.so that
+ can then be integrated into your project as a prebuilt
+ shared library. See the android section on
+ http://wiki.call-cc.org/embedding for a complete example.
+
+ - It is possible to use eggs, by copying them into the right
+ place and probably renaming the files. This is somewhat
+ awkward and requires various hacks to make the
+ loading/linking of eggs work. It may be easier to build
+ the eggs you need manually and linking them statically to
+ your executable.
+
+ - By default debug-logging is enabled and written to the
+ Android log.
+
FreeBSD/NetBSD/OpenBSD:
- *BSD system users *must* use GNU make ("gmake") - the makefiles
diff --git a/chicken.h b/chicken.h
index 51adeba9..bd6c23d7 100644
--- a/chicken.h
+++ b/chicken.h
@@ -657,6 +657,8 @@ static inline int isinf_ld (long double x)
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(_WIN32) || defined(__WINNT__)
# define C_SOFTWARE_TYPE "windows"
+#elif defined(__ANDROID__)
+# define C_SOFTWARE_TYPE "android"
#elif defined(__unix__) || defined(C_XXXBSD) || defined(_AIX)
# define C_SOFTWARE_TYPE "unix"
#elif defined(ECOS)
diff --git a/distribution/manifest b/distribution/manifest
index 10034894..682587ee 100644
--- a/distribution/manifest
+++ b/distribution/manifest
@@ -218,6 +218,7 @@ apply-hack.ppc.darwin.S
apply-hack.ppc.sysv.S
chicken.pdf
Makefile
+Makefile.android
Makefile.aix
Makefile.linux
Makefile.macosx
diff --git a/manual/Unit posix b/manual/Unit posix
index d27fa88a..1ede6c09 100644
--- a/manual/Unit posix
+++ b/manual/Unit posix
@@ -806,6 +806,10 @@ directory and the default shell. When {{AS-VECTOR}} is {{#t}} a vector of 7
elements is returned instead of a list. If no user with this name or id then
{{#f}} is returned.
+Note: on Android systems, the user-specific string is always {{""}},
+since {{pw_gecos}} is not available in the C {{passwd}} struct on that
+platform.
+
==== current-group-id
<procedure>(current-group-id)</procedure>
diff --git a/posixunix.scm b/posixunix.scm
index 6a429117..da0d9f91 100644
--- a/posixunix.scm
+++ b/posixunix.scm
@@ -133,6 +133,14 @@ static C_TLS struct {
char *gr_mem[ 1 ];
} C_group = { "", "", 0, { "" } };
#endif
+
+/* Android doesn't provide pw_gecos in the passwd struct */
+#ifdef __ANDROID__
+# define C_PW_GECOS ("")
+#else
+# define C_PW_GECOS (C_user->pw_gecos)
+#endif
+
static C_TLS int C_pipefds[ 2 ];
static C_TLS time_t C_secs;
static C_TLS struct timeval C_timeval;
@@ -176,7 +184,7 @@ static C_TLS struct stat C_statbuf;
#define C_do_readlink(f, b) C_fix(readlink(C_data_pointer(f), C_data_pointer(b), FILENAME_MAX))
#define C_getpwnam(n) C_mk_bool((C_user = getpwnam((char *)C_data_pointer(n))) != NULL)
#define C_getpwuid(u) C_mk_bool((C_user = getpwuid(C_unfix(u))) != NULL)
-#ifdef HAVE_GRP_H
+#if !defined(__ANDROID__) && defined(HAVE_GRP_H)
#define C_getgrnam(n) C_mk_bool((C_group = getgrnam((char *)C_data_pointer(n))) != NULL)
#define C_getgrgid(u) C_mk_bool((C_group = getgrgid(C_unfix(u))) != NULL)
#else
@@ -290,7 +298,7 @@ static C_TLS sigset_t C_sigset;
#define C_ctime(n) (C_secs = (n), ctime(&C_secs))
-#if defined(__SVR4) || defined(C_MACOSX) || defined(_AIX)
+#if defined(__SVR4) || defined(C_MACOSX) || defined(__ANDROID__) || defined(_AIX)
/* Seen here: http://lists.samba.org/archive/samba-technical/2002-November/025571.html */
static time_t C_timegm(struct tm *t)
@@ -368,7 +376,7 @@ static gid_t *C_groups = NULL;
#define C_set_gid(n, id) (C_groups[ C_unfix(n) ] = C_unfix(id), C_SCHEME_UNDEFINED)
#define C_set_groups(n) C_fix(setgroups(C_unfix(n), C_groups))
-#ifdef TIOCGWINSZ
+#if !defined(__ANDROID__) && defined(TIOCGWINSZ)
static int get_tty_size(int p, int *rows, int *cols)
{
struct winsize tty_size;
@@ -976,7 +984,7 @@ EOF
(define-foreign-variable _user-passwd nonnull-c-string "C_user->pw_passwd")
(define-foreign-variable _user-uid int "C_user->pw_uid")
(define-foreign-variable _user-gid int "C_user->pw_gid")
-(define-foreign-variable _user-gecos nonnull-c-string "C_user->pw_gecos")
+(define-foreign-variable _user-gecos nonnull-c-string "C_PW_GECOS")
(define-foreign-variable _user-dir c-string "C_user->pw_dir")
(define-foreign-variable _user-shell c-string "C_user->pw_shell")
diff --git a/runtime.c b/runtime.c
index a58eb809..c90b9ddd 100644
--- a/runtime.c
+++ b/runtime.c
@@ -37,6 +37,10 @@
# include <sysexits.h>
#endif
+#ifdef __ANDROID__
+# include <android/log.h>
+#endif
+
#if !defined(PIC)
# define NO_DLOAD2
#endif
@@ -536,12 +540,16 @@ C_dbg(C_char *prefix, C_char *fstr, ...)
{
va_list va;
+ va_start(va, fstr);
+#ifdef __ANDROID__
+ __android_log_vprint(ANDROID_LOG_DEBUG, prefix, fstr, va);
+#else
C_fflush(C_stdout);
C_fprintf(C_stderr, "[%s] ", prefix);
- va_start(va, fstr);
C_vfprintf(C_stderr, fstr, va);
- va_end(va);
C_fflush(C_stderr);
+#endif
+ va_end(va);
}
@@ -634,6 +642,10 @@ int CHICKEN_initialize(int heap, int stack, int symbols, void *toplevel)
if(chicken_is_initialized) return 1;
else chicken_is_initialized = 1;
+#ifdef __ANDROID__
+ debug_mode = 2;
+#endif
+
if(debug_mode)
C_dbg(C_text("debug"), C_text("application startup...\n"));
Trap