NOTE: The following information is ancient info on how to compile CouchDB 1.x for Android. You probably really, really don't want this. Modern users will prefer to use https://pouchdb.com/ for almost all needs.
Another old resource that may help is at https://github.com/couchbaselabs/Android-Couchbase-SourceBuild .
Below are updated instructions that produce a build that is better organized for Android, somewhat more lightweight in the final product and slightly more straightforward to understand (and with support for replications over a SSH reverse proxy!). This build requires updates to the Android installer that have not yet been pushed upstream so please don't expect this to work out-of-the-box.
This build passes all of the Futon Test Suite with the exception of the "stats" test which fails with Assertion failed: We managed to force a all_dbs_active error. Please help me to figure out why this is happening.
As alluded to below, I was unable to get Couch to agree to link with the static Spidermonkey library. This is due to the fact that C++ support in more recent official releases of the Google SDK/NDK is lacking. It would be preferable to link statically because it would remove the need for a separate file (libmozjs.so) and thus one less thing to go wrong (there are several workarounds below & in related patches for the fact that we need to worry about dynamic linking with regards to the default couch query server, couchjs).
You will need to replace com.your.namespace with something appropriate for your project throughout the instructions below and in the related patches.
Due to Android's preferences for where files "should be placed" you will need to update several paths below related to com.your.namespace.
Also, if you are not producing an official build of Couch, be sure use a port other than 5984 to avoid clobbering the official builds.
Once installed you will probably want to interact with Futon on Android from your workstation. Run $ adb forward tcp:5985 tcp:5984 and point your web browser to http://localhost:5985 to access Couch. Note that some of the test suite expects to be run from :5984 and will fail when accessed through this configuration (although we only noticed this when building Couch 1.0.1 -- the problem appears to have disappeared in Couch 1.0.2). To run the complete set of tests you will need to stop your local Couch instance (if any) and set the forward up on :5984 on both ends. You will also need to stop www from being removed from the build (we got rid of Futon to save space -- at this point it is only useful to developers anyway).
A lot of the credit should go to Aaron Miller for doing the original port upon which these instructions are based. I would also like to thank Wes and Chris C. Coulson from #jsapi and Dale Harvey, davisp and rnewson from #couchdb. Thanks to everyone else who helped, too.
The following build instructions are intended for Android 2.2.2 and were run on Debian Squeeze. The "scripts" below were run with Bash from a single directory that I called android-build.
I used Java 1.5.0.22 to build Android from source. You will also need an SDK (I used r08).
See couch-android-launcher and libcouch-android for the end-user Android application that will use the package produced by this build.
Supporting these builds are a number of helper scripts and patches, see below.
cd ~/software/android/sdk/sources repo init -b froyo repo sync source build/envsetup.sh export JAVA_HOME=$HOME/software/jdk1.5.0_22 export ANDROID_JAVA_HOME=$JAVA_HOME export PATH=$JAVA_HOME/bin:$PATH lunch make -s
VERSION=7.20.0 [[ -f curl-$VERSION.tar.bz2 ]] || wget http://curl.haxx.se/download/curl-$VERSION.tar.bz2 rm -rf curl-$VERSION tar jxf curl-$VERSION.tar.bz2 cd curl-$VERSION # See AndroidEnv in Installing_on_Android wiki topic source $HOME/software/android/scripts/env ANDROID_SDK=$HOME/software/android/sdk CPPFLAGS="-I$ANDROID_SDK/sources/external/openssl/include -I$ANDROID_SDK/sources/external/zlib" \ CC=agcc \ ./configure \ --disable-shared \ --without-random \ --host=arm-linux --disable-tftp \ --disable-sspi \ --disable-ipv6 \ --disable-ldaps \ --disable-ldap \ --disable-telnet \ --disable-pop3 \ --disable-ftp \ --with-ssl=$ANDROID_SDK/sources/external/openssl \ --disable-imap \ --disable-smtp \ --disable-pop3 \ --disable-rtsp \ --disable-ares \ --without-ca-bundle \ --disable-warnings \ --disable-manual \ --without-nss \ --with-zlib=$ANDROID_SDK/sources/external/zlib make -s
The following instructions are based on the Fennec instructions for building JS/NSPR only. We used their Android NDK package for the builds.
HGREV=bb9089ae2322 [[ -f mozilla-central-$HGREV.tar.bz2 ]] || wget http://hg.mozilla.org/mozilla-central/archive/$HGREV.tar.bz2 rm -rf mozilla-central mozilla-central-$HGREV tar -jxf mozilla-central-$HGREV.tar.bz2 ln -s mozilla-central-$HGREV mozilla-central cd mozilla-central # Use of __android_log_print and __android_log_write requires liblog.so from our # toolchain. However, llog also has a dependency on libstdc++.so which our toolchain # DOES NOT have so we need to substitute for something less Androidy (apologies). patch -p1 < ../mozilla-central.patch
NSPR isn't technically required but it is heavily integrated into current versions of Spidermonkey and future versions will almost certainly require it.
Also, NSPR will compile against current NDKs but I choose to use the recommended one (ndk-r4c-0moz3) for the sake of consistency. The next step (Spidermonkey) requires the specified NDK version.
source $HOME/software/android/scripts/env ANDROID_NDK=$HOME/software/android/android-ndk-r4c cd mozilla-central/nsprpub ./configure \ --target=arm-android-eabi \ --with-android-ndk=$ANDROID_NDK \ --with-android-platform=$ANDROID_NDK/build/platforms/android-8/arch-arm \ --enable-strip make -s # Remove shared libraries so that Couch is built with the static ones rm dist/lib/*so
Be aware that Spidermonkey will not build against Android NDK r5 (we haven't checked this issue recently, it may have changed).
ANDROID_NDK=$HOME/software/android/android-ndk-r4c cd mozilla-central/js/src autoconf2.13 ./configure \ --target=arm-android-eabi \ --with-android-ndk=$ANDROID_NDK \ --with-android-sdk=$ANDROID_NDK/build/platforms/android-8 \ --with-android-version=8 \ --disable-tests \ --disable-shared \ --enable-static \ --enable-strip \ --enable-endian=little \ --with-arm-kuser \ --enable-threadsafe \ --with-nspr-cflags=-I$(pwd)/../../nsprpub/dist/include/nspr \ --with-nspr-libs="-L$(pwd)/../../nsprpub/dist/lib -lnspr4 -lplc4 -lplds4" make -s ## # Remove the shared lib to force Couch to link statically # (this isn't working due to Android toolchain difficulties) # #rm libmozjs.so #mv libjs_static.a libmozjs.a
You should add --enable-debug and --disable-optimizations for development builds or when running the Futon test suite for the first time (assertions matter).
An updated port of Erlang that will work on Android would be greatly appreciated! I know there has been some work on this by the Erlang folks but I am not aware of the location of the build instructions, source code or patches.
rm -rf otp rm -rf otp_rel git clone git://github.com/apage43/otp.git cd otp git checkout origin/android ## # 1) Add back in support for the "beam" binary # 2) Our default autoconf is 2.67 and we need to switch back to 2.59 # for this operation # 3) Environment differences between Android and UNIX (bin/sh) # patch -p1 < ../otp.patch source $HOME/software/android/scripts/env export ANDROID_SDK=$HOME/software/android/sdk export ANDROID_SYS_ROOT=$ANDROID_SDK/sources ./otp_build autoconf ./otp_build configure --xcomp-conf=xcomp/erl-xcomp-android.conf ./otp_build boot -a ./otp_build release -a $(pwd)/../otp_rel
rm -rf couchdb rm -rf /sdcard/* git clone git://github.com/apache/couchdb.git cd couchdb git checkout 1.0.2 ## # 1) Android Build Support from https://github.com/apage43/couchdb/tree/0.11.x-android # 2) Mozilla JS compatibility by chrisccoulson from jsapi@irc.mozilla.org # 3) Fixes for Android by matt.adams-couch@radicaldynamic.com # patch -p1 < ../couchdb.patch ./bootstrap source $HOME/software/android/scripts/env ANDROID_SDK=$HOME/software/android/sdk ERL=$(pwd)/../otp/bootstrap/bin/erl \ ERLC=$(pwd)/../otp/bootstrap/bin/erlc \ CC=agcc \ ./configure \ --host=arm-eabi \ --prefix=/sdcard/Android/data/com.your.namespace/couchdb \ --with-android=$ANDROID_SDK/sources \ --with-android-curl=$(pwd)/../curl-7.20.0 \ --with-erlang=$(pwd)/../otp_rel/usr/include \ --with-js-include=$(pwd)/../mozilla-central/js/src/dist/include \ --with-js-lib="$(pwd)/../mozilla-central/js/src" make -s make install
if [ -z "$1" ]; then echo "Give me a release number bub!" exit 1 fi DATE=$(date +"%Y-%m-%d_%H-%M-%S") RELEASE="release-$DATE" mkdir -p $RELEASE/data/data/com.your.namespace ## # Configure and package Erlang/OTP # cp -Rdp otp_rel otp_rel.package cd otp_rel.package ./Install -cross -sasl /data/data/com.your.namespace/erlang rm Install # Necessary? chmod -x erts-5.7.5/bin/start_erl.src erts-5.7.5/bin/start.src # Remove unnecessary files rm -rf erts-5.7.5/doc erts-5.7.5/include erts-5.7.5/man erts-5.7.5/src misc releases usr # Pare lib directory libs_to_keep="crypto-1.6.4 erts-5.7.5 inets-5.3 kernel-2.13.5 public_key-0.5 sasl-2.1.9 ssl-3.10.8 stdlib-1.16.5 xmerl-1.2.4" cd lib mkdir backuplib for i in $libs_to_keep do mv $i backuplib/ done mv backuplib ../ rm -rf * mv ../backuplib/* . rmdir ../backuplib # Remove vestigal files find . -depth -name src -type d -exec rm -rf {} \; find . -depth -name examples -type d -exec rm -rf {} \; find . -depth -name include -type d -exec rm -rf {} \; cd ../.. ## # Finally move things into place # cp -Rdp /sdcard $RELEASE/sdcard mv otp_rel.package $RELEASE/sdcard/Android/data/com.your.namespace/erlang # We need the shared lib because our toolchain does not support the static lib (libstdc++ stuff) cp mozilla-central/js/src/libmozjs.so $RELEASE/sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/bin ### # 1) DNS fixes from apage43's couchdb-android.s3.amazonaws.com/dns-fix.tgz # 2) Create couchjs_wrapper script (because we can't link to libmozjs.a and so need LD_LIBRARY_PATH set) # 3) Update #!/bin/sh in data/data/com.your.namespace/erlang/lib/couch-1.0.1/priv/couchspawnkillable # 4) Reflect new locations and the Android environment # rm release ln -s $RELEASE release patch -p0 < release.patch chmod +x $RELEASE/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs_wrapper # Build ICU for whatever version of Android was compiled in ~/software/android/sdk/sources source $HOME/software/android/scripts/env agcc \ -shared \ -o $RELEASE/sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/couch_icu_driver.so couchdb/src/couchdb/priv/.libs/libcouch_icu_driver.a \ -licuuc \ -licudata \ -licui18n \ -L$HOME/projects/couch/android-build/otp_rel/erts-5.7.5/bin \ -lbeam ## # Remove vestigal files from Couch directory # (Futon is in www) # cd $RELEASE/sdcard/Android/data/com.your.namespace/couchdb rm -rf share/couchdb/www share/doc share/man cd ../../../../../.. ## # Archive the release # cd $RELEASE # filecount. is used so we can present a progress-based indicator during install touch filecount.$(find | wc -l) tar -czf ../release-$1.tgz filecount.* data sdcard cd ..
This script simply sets up a good environment for building with Android.
paths=" $HOME/software/android/scripts $HOME/software/android/other/apk $HOME/software/android/sdk/platform-tools $HOME/software/android/sdk/platforms/android-8/tools $HOME/software/android/sdk/sources/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin $HOME/software/android/sdk/tools " for i in $paths do if [[ -d $i ]]; then PATH=$PATH:$i fi done export PATH # Java stuff for building Android from sources echo "For building Android from sources:" echo "$ export JAVA_HOME=$HOME/software/jdk1.5.0_22" echo "$ export ANDROID_JAVA_HOME=\$JAVA_HOME" echo "$ export PATH=\$JAVA_HOME/bin:$PATH" echo "$ cd $HOME/software/android/sdk/sources" echo "$ source build/envsetup.sh" echo "$ lunch" echo "$ make"
The Android toolchain is a little complicated so I used http://plausible.org/andy/agcc [dead link, try https://github.com/nitomartinez/agcc instead] to simplify the process. Here is my patch against that script:
--- agcc.old 2011-01-23 19:47:49.000000000 -0700 +++ agcc 2011-01-29 15:43:58.000000000 -0700 @@ -39,7 +39,10 @@ my $DROID = $1; my $ALIB = "$DROID/out/target/product/generic/obj/lib"; -my $TOOLCHAIN = "$DROID/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1"; +my $TOOLCHAIN = "$DROID/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0"; + +print STDERR "ALIB ........ $ALIB\n"; +print STDERR "TOOLCHAIN ... $TOOLCHAIN\n"; my @include_paths = ( "-I$DROID/system/core/include", @@ -85,6 +88,7 @@ "-mthumb-interwork", "-fpic", "-fno-exceptions", + "-fno-short-enums", # See www for why we added this "-ffunction-sections", "-funwind-tables", # static exception-like tables "-fstack-protector", # check guard variable before return @@ -114,7 +118,7 @@ "-nostdlib", "$ALIB/crtend_android.o", "$ALIB/crtbegin_dynamic.o", - "$TOOLCHAIN/lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a", + "$TOOLCHAIN/lib/gcc/arm-eabi/4.4.0/interwork/libgcc.a", "-lc", "-lm"); @@ -129,7 +133,7 @@ "-lc", "-lm", "-Wl,--no-undefined", - "$TOOLCHAIN/lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a", + "$TOOLCHAIN/lib/gcc/arm-eabi/4.4.0/interwork/libgcc.a", "-Wl,--whole-archive"); # .a, .o input files go *after* here # Now implement a quick parser for a gcc-like command line
This old patch to 1.0.2 was apparently necessary to get CouchDB to compile on Android. Your mileage may vary.
diff --git a/configure.ac b/configure.ac index c609a08..a31bc7b 100644 --- a/configure.ac +++ b/configure.ac @@ -118,6 +118,21 @@ Is the Mozilla SpiderMonkey library installed?])])])])]) AC_SUBST(JS_LIB_BASE) +AC_CHECK_LIB([$JS_LIB_BASE], [JS_FreezeObject], + AC_DEFINE([HAVE_JS_FREEZE_OBJECT], [1], [Define whether we have JS_FreezeObject])) + +AC_CHECK_LIB([$JS_LIB_BASE], [JS_NewGlobalObject], + AC_DEFINE([HAVE_JS_NEW_GLOBAL_OBJECT], [1], [Define whether we have JS_NewGlobalObject])) + +AC_CHECK_LIB([$JS_LIB_BASE], [js_fgets], + AC_DEFINE([HAVE_JS_FGETS], [1], [Define whether js_fgets is available to use])) + +AC_CHECK_LIB([$JS_LIB_BASE], [JS_GetStringCharsAndLength], + AC_DEFINE([HAVE_JS_GET_STRING_CHARS_AND_LENGTH], [1], [Define whether we have JS_GetStringCharsAndLength])) + +AC_CHECK_LIB([$JS_LIB_BASE], [JS_NewCompartmentAndGlobalObject], + AC_DEFINE([HAVE_COMPARTMENTS], [1], [Define whether we have JS_NewCompartmentAndGlobalObject])) + if test x${IS_WINDOWS} = xTRUE; then if test -f "$JS_LIB_DIR/$JS_LIB_BASE.dll"; then # seamonkey 1.7- build layout on Windows @@ -189,6 +204,13 @@ AC_COMPILE_IFELSE( CFLAGS="$OLD_CFLAGS" AC_LANG_POP(C) +AC_ARG_WITH([android], [AC_HELP_STRING([--with-android=PATH] + [set Android system build path])],[ + ICU_CONFIG="" + ICU_LOCAL_CFLAGS="-I$withval/external/icu4c/common -I$withval/external/icu4c/i18n" + ICU_LOCAL_LDFLAGS="-L$withval/out/target/product/generic/system/lib" + ICU_LOCAL_BIN= +], [ AC_ARG_WITH([win32-icu-binaries], [AC_HELP_STRING([--with-win32-icu-binaries=PATH], [set PATH to the Win32 native ICU binaries directory])], [ ICU_CONFIG="" # supposed to be a command to query options... @@ -200,13 +222,19 @@ AC_ARG_WITH([win32-icu-binaries], [AC_HELP_STRING([--with-win32-icu-binaries=PAT ICU_LOCAL_CFLAGS=`$ICU_CONFIG --cppflags-searchpath` ICU_LOCAL_LDFLAGS=`$ICU_CONFIG --ldflags-searchpath` ICU_LOCAL_BIN= -]) +])]) AC_SUBST(ICU_CONFIG) AC_SUBST(ICU_LOCAL_CFLAGS) AC_SUBST(ICU_LOCAL_LDFLAGS) AC_SUBST(ICU_LOCAL_BIN) +AC_ARG_WITH([android-curl], [AC_HELP_STRING([--with-android-curl=PATH] + [set PATH to directory where curl is built for android])], [ + CURL_CFLAGS="-I$withval/include -DCURL_STATICLIB" + CURL_LIBDIR="$withval/lib" + CURL_LDFLAGS="-L$CURL_LIBDIR -lcurl" +], [ AC_ARG_WITH([win32-curl], [AC_HELP_STRING([--with-win32-curl=PATH], [set PATH to the Win32 native curl directory])], [ # default build on windows is a static lib, and that's what we want too @@ -216,12 +244,15 @@ AC_ARG_WITH([win32-curl], [AC_HELP_STRING([--with-win32-curl=PATH], ], [ AC_CHECK_CURL([7.18.0]) CURL_LDFLAGS=-lcurl -]) +])]) AC_SUBST(CURL_CFLAGS) AC_SUBST(CURL_LIBS) AC_SUBST(CURL_LDFLAGS) +#Probably should fix this up better in the future for cross-compiles in general +#instead of just keeping this exception for android +if test "x$CC" != "xagcc"; then case "$(uname -s)" in Linux) LIBS="$LIBS -lcrypt" @@ -234,6 +265,7 @@ case "$(uname -s)" in LIBS="$LIBS -lcrypto" ;; esac +fi AC_PATH_PROG([ERL], [erl]) diff --git a/src/couchdb/priv/couch_js/http.c b/src/couchdb/priv/couch_js/http.c index 6c2a8a8..5a2112d 100644 --- a/src/couchdb/priv/couch_js/http.c +++ b/src/couchdb/priv/couch_js/http.c @@ -43,6 +43,10 @@ char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", NULL}; #define DELETE 4 #define COPY 5 +#ifdef JSFUN_CONSTRUCTOR +#define JSFUN_FAST_NATIVE 0 +#endif + static JSBool go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t blen); @@ -50,10 +54,21 @@ static JSString* str_from_binary(JSContext* cx, char* data, size_t length); static JSBool +#ifdef JSFUN_CONSTRUCTOR +constructor(JSContext* cx, uintN argc, jsval* vp) +#else constructor(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) +#endif { HTTPData* http = NULL; JSBool ret = JS_FALSE; +#ifdef JSFUN_CONSTRUCTOR + JSObject* obj = JS_NewObjectForConstructor(cx, vp); + if(!obj) { + JS_ReportError(cx, "Failed to create 'this' object"); + goto error; + } +#endif http = (HTTPData*) malloc(sizeof(HTTPData)); if(!http) @@ -80,6 +95,9 @@ error: if(http) free(http); success: +#ifdef JSFUN_CONSTRUCTOR + JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); +#endif return ret; } @@ -89,7 +107,8 @@ destructor(JSContext* cx, JSObject* obj) HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); if(!http) { - fprintf(stderr, "Unable to destroy invalid CouchHTTP instance.\n"); + // Comment out -- this messes up CouchDB and doesn't seem to be a big deal anyway + //fprintf(stderr, "Unable to destroy invalid CouchHTTP instance.\n"); } else { @@ -100,13 +119,20 @@ destructor(JSContext* cx, JSObject* obj) } static JSBool -open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) -{ +open(JSContext* cx, uintN argc, jsval* vp) +{ + JSBool ret = JS_FALSE; + JSObject* obj = JS_THIS_OBJECT(cx, vp); + if(!obj) { + JS_ReportError(cx, "No 'this' object"); + goto done; + } + HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); char* method = NULL; char* url = NULL; - JSBool ret = JS_FALSE; int methid; + jsval* argv = JS_ARGV(cx, vp); if(!http) { @@ -174,6 +200,7 @@ open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) // Disable Expect: 100-continue http->req_headers = curl_slist_append(http->req_headers, "Expect:"); + JS_SET_RVAL(cx, vp, JSVAL_VOID); ret = JS_TRUE; done: @@ -182,14 +209,21 @@ done: } static JSBool -setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) -{ +setheader(JSContext* cx, uintN argc, jsval* vp) +{ + JSBool ret = JS_FALSE; + JSObject* obj = JS_THIS_OBJECT(cx, vp); + if(!obj) { + JS_ReportError(cx, "No 'this' object"); + goto done; + } + HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); char* keystr = NULL; char* valstr = NULL; char* hdrbuf = NULL; size_t hdrlen = -1; - JSBool ret = JS_FALSE; + jsval* argv = JS_ARGV(cx, vp); if(!http) { @@ -234,6 +268,7 @@ setheader(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) snprintf(hdrbuf, hdrlen, "%s: %s", keystr, valstr); http->req_headers = curl_slist_append(http->req_headers, hdrbuf); + JS_SET_RVAL(cx, vp, JSVAL_VOID); ret = JS_TRUE; done: @@ -245,12 +280,19 @@ done: } static JSBool -sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) +sendreq(JSContext* cx, uintN argc, jsval* vp) { + JSBool ret = JS_FALSE; + JSObject* obj = JS_THIS_OBJECT(cx, vp); + if(!obj) { + JS_ReportError(cx, "No 'this' object"); + goto done; + } + HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj); char* body = NULL; size_t bodylen = 0; - JSBool ret = JS_FALSE; + jsval* argv = JS_ARGV(cx, vp); if(!http) { @@ -270,6 +312,9 @@ sendreq(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) ret = go(cx, obj, http, body, bodylen); + if (ret == JS_TRUE) + JS_SET_RVAL(cx, vp, JSVAL_VOID); + done: if(body) free(body); return ret; @@ -285,7 +330,12 @@ status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) JS_ReportError(cx, "Invalid CouchHTTP instance."); return JS_FALSE; } - +#ifndef INT_FITS_IN_JSVAL + // jsval's are 64-bits wide in mozjs >= 2.0, so a jsint + // can use the full 32-bits now no bits are reserved for tagging + *vp = INT_TO_JSVAL(http->last_status); + return JS_TRUE; +#else if(INT_FITS_IN_JSVAL(http->last_status)) { *vp = INT_TO_JSVAL(http->last_status); @@ -296,6 +346,7 @@ status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp) JS_ReportError(cx, "INTERNAL: Invalid last_status"); return JS_FALSE; } +#endif } JSClass CouchHTTPClass = { @@ -320,9 +371,9 @@ JSPropertySpec CouchHTTPProperties[] = { }; JSFunctionSpec CouchHTTPFunctions[] = { - {"_open", open, 3, 0, 0}, - {"_setRequestHeader", setheader, 2, 0, 0}, - {"_send", sendreq, 1, 0, 0}, + {"_open", open, 3, JSFUN_FAST_NATIVE, 0}, + {"_setRequestHeader", setheader, 2, JSFUN_FAST_NATIVE, 0}, + {"_send", sendreq, 1, JSFUN_FAST_NATIVE, 0}, {0, 0, 0, 0, 0} }; diff --git a/src/couchdb/priv/couch_js/main.c b/src/couchdb/priv/couch_js/main.c index 376aa15..f4bef7c 100644 --- a/src/couchdb/priv/couch_js/main.c +++ b/src/couchdb/priv/couch_js/main.c @@ -28,14 +28,38 @@ int gExitCode = 0; #define FINISH_REQUEST(cx) \ JS_EndRequest(cx); \ JS_ClearContextThread(cx); +#define FINISH_REQUEST_AND_DESTROY(cx) \ + JS_EndRequest(cx); \ + JS_DestroyContext(cx); #else #define SETUP_REQUEST(cx) #define FINISH_REQUEST(cx) +#define FINISH_REQUEST_AND_DESTROY(cx) \ + JS_DestroyContext(cx); +#endif + +#ifdef JSFUN_CONSTRUCTOR +#define JSFUN_FAST_NATIVE 0 #endif +static JSClass global_class = { + "GlobalClass", + JSCLASS_GLOBAL_FLAGS, + JS_PropertyStub, + JS_PropertyStub, + JS_PropertyStub, + JS_PropertyStub, + JS_EnumerateStub, + JS_ResolveStub, + JS_ConvertStub, + JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + static JSBool -evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +evalcx(JSContext* cx, uintN argc, jsval* vp) { + jsval* argv = JS_ARGV(cx, vp); JSString *str; JSObject *sandbox; JSContext *subcx; @@ -43,6 +67,9 @@ evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) size_t srclen; JSBool ret = JS_FALSE; jsval v; +#ifdef HAVE_COMPARTMENTS + JSCrossCompartmentCall *call = NULL; +#endif sandbox = NULL; if(!JS_ConvertArguments(cx, argc, argv, "S / o", &str, &sandbox)) @@ -59,42 +86,70 @@ evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) SETUP_REQUEST(subcx); +#ifdef HAVE_JS_GET_STRING_CHARS_AND_LENGTH + src = JS_GetStringCharsAndLength(cx, str, &srclen); +#else src = JS_GetStringChars(str); srclen = JS_GetStringLength(str); +#endif +#ifdef HAVE_COMPARTMENTS + /* Re-use the compartment associated with the main context, + * rather than creating a new compartment */ + JSObject *global = JS_GetGlobalObject(cx); + if(!global) + { + goto done; + } + call = JS_EnterCrossCompartmentCall(subcx, global); +#endif if(!sandbox) { +#ifdef HAVE_JS_NEW_GLOBAL_OBJECT + sandbox = JS_NewGlobalObject(subcx, &global_class); +#else sandbox = JS_NewObject(subcx, NULL, NULL, NULL); +#endif if(!sandbox || !JS_InitStandardClasses(subcx, sandbox)) goto done; } if(srclen == 0) { - *rval = OBJECT_TO_JSVAL(sandbox); + JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(sandbox)); } else { - JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, rval); + JS_EvaluateUCScript(subcx, sandbox, src, srclen, NULL, 0, &JS_RVAL(cx, vp)); } - + ret = JS_TRUE; done: - FINISH_REQUEST(subcx); - JS_DestroyContext(subcx); +#ifdef HAVE_COMPARTMENTS + if(call) + { + JS_LeaveCrossCompartmentCall(call); + } +#endif + /* Don't use FINISH_REQUEST before destroying a context + * Destroying a context without a thread asserts on threadsafe + * debug builds */ + FINISH_REQUEST_AND_DESTROY(subcx); return ret; } static JSBool -gc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +gc(JSContext* cx, uintN argc, jsval* vp) { JS_GC(cx); + JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } static JSBool -print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +print(JSContext* cx, uintN argc, jsval* vp) { + jsval* argv = JS_ARGV(cx, vp); uintN i; char *bytes; @@ -109,16 +164,52 @@ print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) fputc('\n', stdout); fflush(stdout); + JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; } static JSBool -quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +quit(JSContext* cx, uintN argc, jsval* vp) { + jsval* argv = JS_ARGV(cx, vp); JS_ConvertArguments(cx, argc, argv, "/ i", &gExitCode); return JS_FALSE; } +#ifndef HAVE_JS_FGETS +/* js_fgets is not linkable from C consumers with libmozjs >= 2.0, + * so we reimplement it here */ +#undef js_fgets +static int +couchjs_fgets(char *buf, int size, FILE *file) +{ + int n, i, c; + JSBool crflag; + + n = size - 1; + if (n < 0) + return -1; + + crflag = JS_FALSE; + for (i = 0; i < n && (c = getc(file)) != EOF; i++) { + buf[i] = c; + if (c == '\n') { /* any \n ends a line */ + i++; /* keep the \n; we know there is room for \0 */ + break; + } + if (crflag) { /* \r not followed by \n ends line at the \r */ + ungetc(c, file); + break; /* and overwrite c in buf with \0 */ + } + crflag = (c == '\r'); + } + + buf[i] = '\0'; + return i; +} +#define js_fgets couchjs_fgets +#endif + static char* readfp(JSContext* cx, FILE* fp, size_t* buflen) { @@ -130,7 +221,6 @@ readfp(JSContext* cx, FILE* fp, size_t* buflen) bytes = JS_malloc(cx, byteslen); if(bytes == NULL) return NULL; - while((readlen = js_fgets(bytes+used, byteslen-used, stdin)) > 0) { used += readlen; @@ -157,7 +247,7 @@ readfp(JSContext* cx, FILE* fp, size_t* buflen) } static JSBool -readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { +readline(JSContext* cx, uintN argc, jsval* vp) { jschar *chars; JSString *str; char* bytes; @@ -173,9 +263,10 @@ readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { /* Treat the empty string specially */ if(byteslen == 0) { - *rval = JS_GetEmptyStringValue(cx); + //JS_SET_RVAL(cx, vp, JS_GetEmptyStringValue(cx)); JS_free(cx, bytes); - return JS_TRUE; + //return JS_TRUE; + return JS_FALSE; } /* Shrink the buffer to the real size */ @@ -191,22 +282,32 @@ readline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JS_free(cx, bytes); if(!str) return JS_FALSE; - - *rval = STRING_TO_JSVAL(str); + JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str)); return JS_TRUE; } static JSBool -seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { +seal(JSContext* cx, uintN argc, jsval* vp) { + jsval* argv = JS_ARGV(cx, vp); JSObject *target; JSBool deep = JS_FALSE; if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep)) return JS_FALSE; - if (!target) + if (!target) { + JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; - return JS_SealObject(cx, target, deep); + } +#ifdef HAVE_JS_FREEZE_OBJECT + JSBool res = deep ? JS_DeepFreezeObject(cx, target) : JS_FreezeObject(cx, target); +#else + JSBool res = JS_SealObject(cx, target, deep); +#endif + if (res == JS_TRUE) + JS_SET_RVAL(cx, vp, JSVAL_VOID); + + return res; } static void @@ -248,29 +349,15 @@ printerror(JSContext *cx, const char *mesg, JSErrorReport *report) } static JSFunctionSpec global_functions[] = { - {"evalcx", evalcx, 0, 0, 0}, - {"gc", gc, 0, 0, 0}, - {"print", print, 0, 0, 0}, - {"quit", quit, 0, 0, 0}, - {"readline", readline, 0, 0, 0}, - {"seal", seal, 0, 0, 0}, + {"evalcx", evalcx, 0, JSFUN_FAST_NATIVE, 0}, + {"gc", gc, 0, JSFUN_FAST_NATIVE, 0}, + {"print", print, 0, JSFUN_FAST_NATIVE, 0}, + {"quit", quit, 0, JSFUN_FAST_NATIVE, 0}, + {"readline", readline, 0, JSFUN_FAST_NATIVE, 0}, + {"seal", seal, 0, JSFUN_FAST_NATIVE, 0}, {0, 0, 0, 0, 0} }; -static JSClass global_class = { - "GlobalClass", - JSCLASS_GLOBAL_FLAGS, - JS_PropertyStub, - JS_PropertyStub, - JS_PropertyStub, - JS_PropertyStub, - JS_EnumerateStub, - JS_ResolveStub, - JS_ConvertStub, - JS_FinalizeStub, - JSCLASS_NO_OPTIONAL_MEMBERS -}; - int main(int argc, const char * argv[]) { @@ -290,9 +377,18 @@ main(int argc, const char * argv[]) JS_ToggleOptions(cx, JSOPTION_XML); SETUP_REQUEST(cx); - +#ifdef HAVE_COMPARTMENTS + global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); + if (!global) return 1; + JSCrossCompartmentCall *call = JS_EnterCrossCompartmentCall(cx, global); +#elif HAVE_JS_NEW_GLOBAL_OBJECT + global = JS_NewGlobalObject(cx, &global_class); + if (!global) return 1; +#else global = JS_NewObject(cx, &global_class, NULL, NULL); if (!global) return 1; + JS_SetGlobalObject(cx, global); +#endif if (!JS_InitStandardClasses(cx, global)) return 1; for(sp = global_functions; sp->name != NULL; sp++) @@ -309,8 +405,6 @@ main(int argc, const char * argv[]) { return 1; } - - JS_SetGlobalObject(cx, global); if(argc > 2) { @@ -328,9 +422,15 @@ main(int argc, const char * argv[]) execute_script(cx, global, argv[1]); } - FINISH_REQUEST(cx); +#ifdef HAVE_COMPARTMENTS + JS_LeaveCrossCompartmentCall(call); +#endif + + /* Don't use FINISH_REQUEST before destroying a context + * Destroying a context without a thread asserts on threadsafe + * debug builds */ + FINISH_REQUEST_AND_DESTROY(cx); - JS_DestroyContext(cx); JS_DestroyRuntime(rt); JS_ShutDown(); diff --git a/src/couchdb/priv/couch_js/utf8.c b/src/couchdb/priv/couch_js/utf8.c index 699a6fe..b088020 100644 --- a/src/couchdb/priv/couch_js/utf8.c +++ b/src/couchdb/priv/couch_js/utf8.c @@ -12,6 +12,8 @@ #include <jsapi.h> +#include "config.h" + static int enc_char(uint8 *utf8Buffer, uint32 ucs4Char) { @@ -129,8 +131,12 @@ enc_string(JSContext* cx, jsval arg, size_t* buflen) str = JS_ValueToString(cx, arg); if(!str) goto error; +#ifdef HAVE_JS_GET_STRING_CHARS_AND_LENGTH + src = JS_GetStringCharsAndLength(cx, str, &srclen); +#else src = JS_GetStringChars(str); srclen = JS_GetStringLength(str); +#endif if(!enc_charbuf(src, srclen, NULL, &byteslen)) goto error; @@ -283,4 +289,4 @@ error: success: return str; -} \ No newline at end of file +}
The following patch was apparently necessary to get SpiderMonkey 1.8.5 to compile on Android. Your mileage may vary.
--- mozilla-central-bb9089ae2322/nsprpub/pr/src/io/prlog.c 2011-01-21 16:40:14.000000000 -0700 +++ mozilla-central-bb9089ae2322.bak/nsprpub/pr/src/io/prlog.c 2011-01-31 13:53:30.000000000 -0700 @@ -42,7 +42,7 @@ #include "prprf.h" #include <string.h> #ifdef ANDROID -#include <android/log.h> +//#include <android/log.h> #endif /* @@ -135,7 +135,7 @@ if (fd == _pr_stderr) { \ char savebyte = buf[nb]; \ buf[nb] = '\0'; \ - __android_log_write(ANDROID_LOG_INFO, "PRLog", buf); \ + printf("PRLog: %s", buf); \ buf[nb] = savebyte; \ } else { \ PR_Write(fd, buf, nb); \ --- mozilla-central-bb9089ae2322/js/src/jscntxt.cpp 2011-01-21 16:40:14.000000000 -0700 +++ mozilla-central-bb9089ae2322.bak/js/src/jscntxt.cpp 2011-01-31 13:49:52.000000000 -0700 @@ -46,7 +46,7 @@ #include <stdlib.h> #include <string.h> #ifdef ANDROID -# include <android/log.h> +//# include <android/log.h> # include <fstream> # include <string> #endif // ANDROID @@ -2218,12 +2218,14 @@ // Check for the known-bad kernel version (2.6.29). std::ifstream osrelease("/proc/sys/kernel/osrelease"); std::getline(osrelease, line); - __android_log_print(ANDROID_LOG_INFO, "Gecko", "Detected osrelease `%s'", - line.c_str()); +// __android_log_print(ANDROID_LOG_INFO, "Gecko", "Detected osrelease `%s'", +// line.c_str()); + printf("Gecko: Detected osrelease `%s'", line.c_str()); if (line.npos == line.find("2.6.29")) { // We're using something other than 2.6.29, so the JITs should work. - __android_log_print(ANDROID_LOG_INFO, "Gecko", "JITs are not broken"); +// __android_log_print(ANDROID_LOG_INFO, "Gecko", "JITs are not broken"); + printf("Gecko: JITs are not broken"); return false; } @@ -2243,8 +2245,9 @@ }; for (const char** hw = &blacklist[0]; *hw; ++hw) { if (line.npos != line.find(*hw)) { - __android_log_print(ANDROID_LOG_INFO, "Gecko", - "Blacklisted device `%s'", *hw); +// __android_log_print(ANDROID_LOG_INFO, "Gecko", +// "Blacklisted device `%s'", *hw); + printf("Gecko: Blacklisted device `%s'", *hw); broken = true; break; } @@ -2254,8 +2257,9 @@ std::getline(cpuinfo, line); } while(!cpuinfo.fail() && !cpuinfo.eof()); - __android_log_print(ANDROID_LOG_INFO, "Gecko", "JITs are %sbroken", - broken ? "" : "not "); +// __android_log_print(ANDROID_LOG_INFO, "Gecko", "JITs are %sbroken", +// broken ? "" : "not "); + printf("Gecko: JITs are %sborken", broken ? "" : "not "); return broken; #endif // ifndef ANDROID --- mozilla-central/nsprpub/pr/src/Makefile.in.bak 2011-02-02 15:39:53.000000000 -0700 +++ mozilla-central/nsprpub/pr/src/Makefile.in 2011-02-02 15:40:07.000000000 -0700 @@ -205,9 +205,9 @@ OS_LIBS = ws2.lib endif -ifeq ($(OS_TARGET),Android) -OS_LIBS += -llog -endif +#ifeq ($(OS_TARGET),Android) +#OS_LIBS += -llog +#endif ifeq ($(OS_TARGET),MacOSX) OS_LIBS = -framework CoreServices -framework CoreFoundation --- mozilla-central/js/src/configure.in.bak 2011-02-02 15:41:20.000000000 -0700 +++ mozilla-central/js/src/configure.in 2011-02-02 15:41:43.000000000 -0700 @@ -291,11 +291,10 @@ CFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions -march=armv5te -mthumb-interwork $CFLAGS" CXXFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions -march=armv5te -mthumb-interwork $CXXFLAGS" - dnl Add -llog by default, since we use it all over the place. dnl Add --allow-shlib-undefined, because libGLESv2 links to an dnl undefined symbol (present on the hardware, just not in the dnl NDK.) - LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -llog -Wl,--allow-shlib-undefined $LDFLAGS" + LDFLAGS="-mandroid -L$android_platform/usr/lib -Wl,-rpath-link=$android_platform/usr/lib --sysroot=$android_platform -Wl,--allow-shlib-undefined $LDFLAGS" dnl prevent cross compile section from using these flags as host flags if test -z "$HOST_CPPFLAGS" ; then
The following patch was apparently necessary to get Erlang/OTP to compile on Android. Your mileage may vary.
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index fb8d718..4ed25c9 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -352,6 +352,7 @@ EMULATOR_EXECUTABLE = beam$(TF_MARKER).dll else ifeq ($(CC), agcc) EMULATOR_EXECUTABLE = libbeam$(TF_MARKER).so +EMULATOR_EXECUTABLE_REG = beam$(TF_MARKER) else EMULATOR_EXECUTABLE = beam$(TF_MARKER) endif @@ -374,7 +375,11 @@ ifeq ($(FLAVOR)-@ERTS_BUILD_SMP_EMU@,smp-no) all: @echo '*** Omitted build of emulator with smp support' else +ifeq ($(CC), agcc) +all: generate erts_lib zlib pcre $(BINDIR)/$(EMULATOR_EXECUTABLE) $(BINDIR)/$(EMULATOR_EXECUTABLE_REG) $(UNIX_ONLY_BUILDS) +else all: generate erts_lib zlib pcre $(BINDIR)/$(EMULATOR_EXECUTABLE) $(UNIX_ONLY_BUILDS) +endif ifeq ($(OMIT_OMIT_FP),yes) @echo '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *' @echo '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *' @@ -453,6 +458,7 @@ release_spec: all $(INSTALL_DATA) $(RELEASE_INCLUDES) $(RELEASE_PATH)/usr/include $(INSTALL_DATA) $(RELEASE_INCLUDES) $(RELSYSDIR)/include $(INSTALL_PROGRAM) $(BINDIR)/$(EMULATOR_EXECUTABLE) $(RELSYSDIR)/bin + $(INSTALL_PROGRAM) $(BINDIR)/$(EMULATOR_EXECUTABLE_REG) $(RELSYSDIR)/bin ifeq ($(ERLANG_OSTYPE), unix) $(INSTALL_PROGRAM) $(BINDIR)/$(CS_EXECUTABLE) $(RELSYSDIR)/bin endif @@ -1013,6 +1019,13 @@ ifeq ($(CC), agcc) $(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS) $(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE) \ $(HIPEBEAMLDFLAGS) $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS) $(LIBS) -shared + +$(OBJDIR)/beam.o: + $(CC) $(CFLAGS) $(INCLUDES) -c beam/beam.c -o $(OBJDIR)/beam.o + +$(BINDIR)/$(EMULATOR_EXECUTABLE_REG): $(OBJDIR)/beam.o + $(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE_REG) \ + $(HIPEBEAMLDFLAGS) $(LDFLAGS) $(DEXPORT) $(OBJDIR)/beam.o $(LIBS) -L$(BINDIR) -lbeam else $(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS) $(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE) \ diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c index 7c6e4a2..c1a1549 100644 --- a/erts/emulator/sys/unix/erl_child_setup.c +++ b/erts/emulator/sys/unix/erl_child_setup.c @@ -116,7 +116,11 @@ main(int argc, char *argv[]) execv(argv[CS_ARGV_NO_OF_ARGS],&(argv[CS_ARGV_NO_OF_ARGS + 1])); } } else { +#ifdef ANDROID_ARM + execl("/system/bin/sh", "sh", "-c", argv[CS_ARGV_CMD_IX], (char *) NULL); +#else execl("/bin/sh", "sh", "-c", argv[CS_ARGV_CMD_IX], (char *) NULL); +#endif } return 1; } diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index 31ab5d0..9a260a2 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -1539,7 +1539,11 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op } } } else { +#ifdef ANDROID_ARM + execle("/system/bin/sh", "sh", "-c", cmd_line, (char *) NULL, new_environ); +#else execle("/bin/sh", "sh", "-c", cmd_line, (char *) NULL, new_environ); +#endif } child_error: _exit(1); @@ -1660,7 +1664,12 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op fcntl(i, F_SETFD, 1); qnx_spawn_options.flags = _SPAWN_SETSID; +#ifdef ANDROID_ARM + /* Are we really in QNX? Then we don't need this special case here... */ + if ((pid = spawnl(P_NOWAIT, "/system/bin/sh", "/system/bin/sh", "-c", cmd_line, +#else if ((pid = spawnl(P_NOWAIT, "/bin/sh", "/bin/sh", "-c", cmd_line, +#endif (char *) 0)) < 0) { erts_free(ERTS_ALC_T_TMP, (void *) cmd_line); reset_qnx_spawn(); diff --git a/erts/emulator/beam/beam.c b/erts/emulator/beam/beam.c new file mode 100644 index 0000000..167b96e --- /dev/null +++ b/erts/emulator/beam/beam.c @@ -0,0 +1,2 @@ +void erl_start(int argc, char** argv); +int main(int argc, char** argv) { erl_start(argc, argv); } diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index 0b39808..5d9658e 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -108,7 +108,7 @@ $(OBJDIR)/%.o: %.c $(LIBDIR)/crypto_drv.so: $(OBJS) $(INSTALL_DIR) $(LIBDIR) - $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB) $(LIBS) -lbeam + $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CRYPTO_LINK_LIB) $(LIBS) -lbeam -shared $(LIBDIR)/crypto_drv.dll: $(OBJS) $(INSTALL_DIR) $(LIBDIR) diff --git a/otp_build b/otp_build index ad9d38e..b875b38 100755 --- a/otp_build +++ b/otp_build @@ -284,7 +284,7 @@ do_autoconf () export WANT_AUTOCONF_VER fi exp_ac_vsn=$EXPECTED_AUTOCONF_VERSION - ac_vsn_blob=`autoconf --version` + ac_vsn_blob=`autoconf2.59 --version` ac_vsn=`echo x$ac_vsn_blob | sed "s|[^0-9]*\([0-9][^ \t\n]*\).*|\1|"` case "$ac_vsn" in $exp_ac_vsn) @@ -327,11 +327,11 @@ do_autoconf () rm -f "$d"/autom4te.cache/* } echo "=== running autoconf in $d" - ( cd "$d" && autoconf ) || exit 1 + ( cd "$d" && autoconf2.59 ) || exit 1 chdr=`cat "$file" | sed -n "s|.*\(AC_CONFIG_HEADER\).*|\1|p"` [ "$chdr" = "AC_CONFIG_HEADER" ] || continue echo "=== running autoheader in $d" - ( cd "$d" && autoheader ) || exit 1 + ( cd "$d" && autoheader2.59 ) || exit 1 done restore_vars OVERRIDE_TARGET TARGET
This final patch was necessary to make the release process for CouchDB work with Android 4.
diff -ru release.bak/sdcard/Android/data/com.your.namespace/couchdb/bin/couchdb release/sdcard/Android/data/com.your.namespace/couchdb/bin/couchdb --- release.bak/sdcard/Android/data/com.your.namespace/couchdb/bin/couchdb 2011-02-05 01:26:00.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/couchdb/bin/couchdb 2011-02-08 16:42:00.000000000 -0700 @@ -12,6 +12,9 @@ # License for the specific language governing permissions and limitations under # the License. +export HOME=/data/data/com.your.namespace +export LD_LIBRARY_PATH=$HOME/erlang/erts-5.7.5/bin:$HOME/couchdb/bin:$HOME/couchdb/lib/couchdb/bin +export PATH=$HOME/erlang/bin:$HOME/couchdb/bin:$PATH BACKGROUND=false DEFAULT_CONFIG_DIR=/sdcard/Android/data/com.your.namespace/couchdb/etc/couchdb/default.d DEFAULT_CONFIG_FILE=/sdcard/Android/data/com.your.namespace/couchdb/etc/couchdb/default.ini @@ -222,8 +225,8 @@ touch $PID_FILE interactive_option="+Bd -noinput" fi - command="/home/matt/projects/couch/android-build/couchdb/../otp/bootstrap/bin/erl $interactive_option $ERL_START_OPTIONS \ - -env ERL_LIBS /sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/erlang/lib -couch_ini $start_arguments -s couch" + command="erl $interactive_option $ERL_START_OPTIONS \ + -env ERL_LIBS /data/data/com.your.namespace/couchdb/lib/couchdb/erlang/lib -couch_ini $start_arguments -s couch" if test "$BACKGROUND" = "true" -a "$RECURSED" = "false"; then $0 $background_start_arguments -b -r $RESPAWN_TIMEOUT -p $PID_FILE \ -o $STDOUT_FILE -e $STDERR_FILE -R & diff -ru release.bak/sdcard/Android/data/com.your.namespace/couchdb/etc/couchdb/local.ini release/sdcard/Android/data/com.your.namespace/couchdb/etc/couchdb/local.ini --- release.bak/sdcard/Android/data/com.your.namespace/couchdb/etc/couchdb/local.ini 2011-02-05 01:26:00.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/couchdb/etc/couchdb/local.ini 2011-02-08 15:58:30.000000000 -0700 @@ -5,23 +5,30 @@ ; overwritten on server upgrade. [couchdb] +database_dir = /sdcard/Android/data/com.your.namespace/couchdb/var/lib/couchdb +view_index_dir = /sdcard/Android/data/com.your.namespace/couchdb/var/lib/couchdb +util_driver_dir = /data/data/com.your.namespace/couchdb/lib/couchdb ;max_document_size = 4294967296 ; bytes +uri_file = /sdcard/Android/data/com.your.namespace/couchdb/var/lib/couchdb/couch.uri [httpd] -;port = 5984 -;bind_address = 127.0.0.1 +port = 5999 +bind_address = 127.0.0.1 ; Uncomment next line to trigger basic-auth popup on unauthorized requests. ;WWW-Authenticate = Basic realm="administrator" +[log] +file = /sdcard/Android/data/com.your.namespace/couchdb/var/log/couchdb/couch.log +level = debug + [couch_httpd_auth] ; If you set this to true, you should also uncomment the WWW-Authenticate line ; above. If you don't configure a WWW-Authenticate header, CouchDB will send ; Basic realm="server" in order to prevent you getting logged out. ; require_valid_user = false -[log] -;level = debug - +[query_servers] +javascript = /data/data/com.your.namespace/couchdb/bin/couchjs_wrapper /data/data/com.your.namespace/couchdb/share/couchdb/server/main.js ; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to ; the Virual Host will be redirected to the path. In the example below all requests diff -ruN release.bak/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs release/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs --- release.bak/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs 2011-02-05 01:26:00.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs 2011-02-05 01:37:12.000000000 -0700 @@ -1,4 +1,4 @@ -#! /bin/sh -e +#!/system/bin/sh -e # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy of @@ -63,7 +63,7 @@ } run_couchjs () { - exec /sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/bin/couchjs $@ + exec LD_LIBRARY_PATH=/data/data/com.your.namespace/couchdb/lib/couchdb/bin /data/data/com.your.namespace/couchdb/lib/couchdb/bin/couchjs $@ } parse_script_option_list () { diff -ruN release.bak/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs_wrapper release/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs_wrapper --- release.bak/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs_wrapper 1969-12-31 17:00:00.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/couchdb/bin/couchjs_wrapper 2011-02-05 01:39:28.000000000 -0700 @@ -0,0 +1,3 @@ +#!/system/bin/sh +export LD_LIBRARY_PATH=/data/data/com.your.namespace/couchdb/lib/couchdb/bin +exec /data/data/com.your.namespace/couchdb/lib/couchdb/bin/couchjs $@ \ No newline at end of file diff -ruN release.bak/sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/erlang/lib/couch-1.0.2/priv/couchspawnkillable release/sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/erlang/lib/couch-1.0.2/priv/couchspawnkillable --- release.bak/sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/erlang/lib/couch-1.0.2/priv/couchspawnkillable 2011-02-05 01:26:00.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/couchdb/lib/couchdb/erlang/lib/couch-1.0.2/priv/couchspawnkillable 2011-02-05 01:48:49.000000000 -0700 @@ -1,4 +1,4 @@ -#! /bin/sh -e +#!/system/bin/sh -e # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy of diff -ruN release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/erl release/sdcard/Android/data/com.your.namespace/erlang/bin/erl --- release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/erl 2011-02-05 01:28:07.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/bin/erl 2011-02-05 01:49:29.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # %CopyrightBegin% # @@ -21,6 +21,7 @@ BINDIR=$ROOTDIR/erts-5.7.5/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\///'` +export ERL_INETRC=$ROOTDIR/bin/erl_inetrc export EMU export ROOTDIR export BINDIR diff -ruN release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/erl_inetrc release/sdcard/Android/data/com.your.namespace/erlang/bin/erl_inetrc --- release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/erl_inetrc 1969-12-31 17:00:00.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/bin/erl_inetrc 2011-02-05 01:49:58.000000000 -0700 @@ -0,0 +1,4 @@ +%% Use erlang's internal resolver. Native DNS on android is annoying +{lookup, [file,dns]}. +%% TODO: Not this, +{nameserver, {8,8,8,8}}. \ No newline at end of file diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/start release/sdcard/Android/data/com.your.namespace/erlang/bin/start --- release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/start 2011-02-05 01:57:26.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/bin/start 2011-02-05 02:05:54.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # %CopyrightBegin% # diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/start_erl release/sdcard/Android/data/com.your.namespace/erlang/bin/start_erl --- release.bak/sdcard/Android/data/com.your.namespace/erlang/bin/start_erl 2011-02-05 01:57:26.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/bin/start_erl 2011-02-05 02:05:48.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # # %CopyrightBegin% diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl --- release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl 2011-02-05 01:57:26.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl 2011-02-05 02:06:04.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # %CopyrightBegin% # diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl.src release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl.src --- release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl.src 2011-02-05 01:23:30.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/erl.src 2011-02-05 02:06:01.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # %CopyrightBegin% # diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start --- release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start 2011-02-05 01:57:26.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start 2011-02-05 02:06:09.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # %CopyrightBegin% # diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start_erl.src release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start_erl.src --- release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start_erl.src 2011-02-05 01:23:30.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start_erl.src 2011-02-05 02:06:06.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # # %CopyrightBegin% diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start.src release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start.src --- release.bak/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start.src 2011-02-05 01:23:30.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/erts-5.7.5/bin/start.src 2011-02-05 02:05:58.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh # # %CopyrightBegin% # diff -ru release.bak/sdcard/Android/data/com.your.namespace/erlang/lib/inets-5.3/priv/bin/runcgi.sh release/sdcard/Android/data/com.your.namespace/erlang/lib/inets-5.3/priv/bin/runcgi.sh --- release.bak/sdcard/Android/data/com.your.namespace/erlang/lib/inets-5.3/priv/bin/runcgi.sh 2011-02-05 01:22:58.000000000 -0700 +++ release/sdcard/Android/data/com.your.namespace/erlang/lib/inets-5.3/priv/bin/runcgi.sh 2011-02-05 02:06:14.000000000 -0700 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/system/bin/sh cd $1 shift exec env "$@"