>From e99ca32efb3fd515435ec86112a46d25be016780 Mon Sep 17 00:00:00 2001 From: felix Date: Wed, 18 Dec 2013 14:36:16 +0100 Subject: [PATCH 1/2] Added Android-specific changes to posix-unit and runtime and added a simple makefile. Signed-off-by: Peter Bex --- Makefile.android | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ README | 24 +++++++++++ chicken.h | 2 + distribution/manifest | 1 + manual/Unit posix | 4 ++ posixunix.scm | 16 ++++++-- runtime.c | 16 +++++++- 7 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 Makefile.android diff --git a/Makefile.android b/Makefile.android new file mode 100644 index 0000000..7aafbd5 --- /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 49abb0d..1720952 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 f61708d..95bdbd2 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 1003489..682587e 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 d27fa88..1ede6c0 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 (current-group-id) diff --git a/posixunix.scm b/posixunix.scm index 8f67848..b9e541e 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 e91d444..9365e1d 100644 --- a/runtime.c +++ b/runtime.c @@ -37,6 +37,10 @@ # include #endif +#ifdef __ANDROID__ +# include +#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")); -- 1.7.9.5