Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

build: add android support

Resolves minor discrepancies between android and standard POSIX systems.
In addition, some configure parameters were added, and a helper-script
for android configuration. Ideally, this script should be merged into
the standard configure script.

To build for android, source the android-configure script with an NDK
path:

    source ./android-configure ~/android-ndk-r8d

This will create an android standalone toolchain and export the
necessary environment parameters.

After that, build as normal:

    make -j8

After the build, you should now have android-compatible NodeJS binaries.
  • Loading branch information...
Linus Mårtensson authored and bnoordhuis committed May 8, 2013
1 parent ffcd8b9 commit 5e4e8ec429381a8d1eebe31647e9daaaae42c54b
Showing with 57 additions and 17 deletions.
  1. +19 −0 android-configure
  2. +11 −3 common.gypi
  3. +4 −1 configure
  4. +14 −7 doc/api/process.markdown
  5. +4 −1 src/cares_wrap.cc
  6. +5 −5 src/node.cc
@@ -0,0 +1,19 @@
#!/bin/bash

export TOOLCHAIN=$PWD/android-toolchain
mkdir -p $TOOLCHAIN
$1/build/tools/make-standalone-toolchain.sh \
--toolchain=arm-linux-androideabi-4.7 \
--arch=arm \
--install-dir=$TOOLCHAIN \
--platform=android-9
export PATH=$TOOLCHAIN/bin:$PATH
export AR=arm-linux-androideabi-ar
export CC=arm-linux-androideabi-gcc
export CXX=arm-linux-androideabi-g++
export LINK=arm-linux-androideabi-g++

./configure \
--without-snapshot \
--dest-cpu=arm \
--dest-os=android
@@ -161,10 +161,14 @@
'BUILDING_UV_SHARED=1',
],
}],
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', '-pthread', ],
[ 'OS in "linux freebsd openbsd solaris"', {
'cflags': [ '-pthread', ],
'ldflags': [ '-pthread' ],
}],
[ 'OS in "linux freebsd openbsd solaris android"', {
'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', ],
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
'ldflags': [ '-pthread', '-rdynamic' ],
'ldflags': [ '-rdynamic' ],
'target_conditions': [
['_type=="static_library"', {
'standalone_static_library': 1, # disable thin archive which needs binutils >= 2.19
@@ -187,6 +191,10 @@
}],
],
}],
[ 'OS=="android"', {
'defines': ['_GLIBCXX_USE_C99_MATH'],
'libraries': [ '-llog' ],
}],
['OS=="mac"', {
'defines': ['_DARWIN_USE_64_BIT_INODE=1'],
'xcode_settings': {
@@ -237,7 +237,7 @@ parser.add_option("--dest-os",
action="store",
dest="dest_os",
help="Operating system to build for. Valid values are: "
"win, mac, solaris, freebsd, openbsd, linux")
"win, mac, solaris, freebsd, openbsd, linux, android")

parser.add_option("--no-ifaddrs",
action="store_true",
@@ -434,6 +434,8 @@ def configure_arm(o):


def configure_node(o):
if options.dest_os == 'android':
o['variables']['OS'] = "android"
o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
@@ -641,6 +643,7 @@ configure_v8(output)
configure_openssl(output)
configure_winsdk(output)


# variables should be a root level element,
# move everything else to target_defaults
variables = output['variables']
@@ -213,7 +213,8 @@ The shell that executed node should see the exit code as 1.

## process.getgid()

Note: this function is only available on POSIX platforms (i.e. not Windows)
Note: this function is only available on POSIX platforms (i.e. not Windows,
Android)

Gets the group identity of the process. (See getgid(2).)
This is the numerical group id, not the group name.
@@ -225,7 +226,8 @@ This is the numerical group id, not the group name.

## process.setgid(id)

Note: this function is only available on POSIX platforms (i.e. not Windows)
Note: this function is only available on POSIX platforms (i.e. not Windows,
Android)

Sets the group identity of the process. (See setgid(2).) This accepts either
a numerical ID or a groupname string. If a groupname is specified, this method
@@ -245,7 +247,8 @@ blocks while resolving it to a numerical ID.

## process.getuid()

Note: this function is only available on POSIX platforms (i.e. not Windows)
Note: this function is only available on POSIX platforms (i.e. not Windows,
Android)

Gets the user identity of the process. (See getuid(2).)
This is the numerical userid, not the username.
@@ -257,7 +260,8 @@ This is the numerical userid, not the username.

## process.setuid(id)

Note: this function is only available on POSIX platforms (i.e. not Windows)
Note: this function is only available on POSIX platforms (i.e. not Windows,
Android)

Sets the user identity of the process. (See setuid(2).) This accepts either
a numerical ID or a username string. If a username is specified, this method
@@ -277,15 +281,17 @@ blocks while resolving it to a numerical ID.

## process.getgroups()

Note: this function is only available on POSIX platforms (i.e. not Windows)
Note: this function is only available on POSIX platforms (i.e. not Windows,
Android)

Returns an array with the supplementary group IDs. POSIX leaves it unspecified
if the effective group ID is included but node.js ensures it always is.


## process.setgroups(groups)

Note: this function is only available on POSIX platforms (i.e. not Windows)
Note: this function is only available on POSIX platforms (i.e. not Windows,
Android)

Sets the supplementary group IDs. This is a privileged operation, meaning you
need to be root or have the CAP_SETGID capability.
@@ -295,7 +301,8 @@ The list can contain group IDs, group names or both.

## process.initgroups(user, extra_group)

Note: this function is only available on POSIX platforms (i.e. not Windows)
Note: this function is only available on POSIX platforms (i.e. not Windows,
Android)

Reads /etc/group and initializes the group access list, using all groups of
which the user is a member. This is a privileged operation, meaning you need
@@ -31,7 +31,10 @@
#include "tree.h"
#include "uv.h"

#if defined(__OpenBSD__) || defined(__MINGW32__) || defined(_MSC_VER)
#if defined(__ANDROID__) || \
defined(__MINGW32__) || \
defined(__OpenBSD__) || \
defined(_MSC_VER)
# include <nameser.h>
#else
# include <arpa/nameser.h>
@@ -61,7 +61,7 @@ typedef int mode_t;
#include <sys/types.h>
#include "zlib.h"

#ifdef __POSIX__
#if defined(__POSIX__) && !defined(__ANDROID__)
# include <pwd.h> /* getpwnam() */
# include <grp.h> /* getgrnam() */
#endif
@@ -1374,7 +1374,7 @@ static Handle<Value> Umask(const Arguments& args) {
}


#ifdef __POSIX__
#if defined(__POSIX__) && !defined(__ANDROID__)

static const uid_t uid_not_found = static_cast<uid_t>(-1);
static const gid_t gid_not_found = static_cast<gid_t>(-1);
@@ -1650,7 +1650,7 @@ static Handle<Value> InitGroups(const Arguments& args) {
return Undefined(node_isolate);
}

#endif // __POSIX__
#endif // __POSIX__ && !defined(__ANDROID__)


v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
@@ -2349,7 +2349,7 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {

NODE_SET_METHOD(process, "umask", Umask);

#ifdef __POSIX__
#if defined(__POSIX__) && !defined(__ANDROID__)
NODE_SET_METHOD(process, "getuid", GetUid);
NODE_SET_METHOD(process, "setuid", SetUid);

@@ -2359,7 +2359,7 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
NODE_SET_METHOD(process, "getgroups", GetGroups);
NODE_SET_METHOD(process, "setgroups", SetGroups);
NODE_SET_METHOD(process, "initgroups", InitGroups);
#endif // __POSIX__
#endif // __POSIX__ && !defined(__ANDROID__)

NODE_SET_METHOD(process, "_kill", Kill);

6 comments on commit 5e4e8ec

@ry

This comment has been minimized.

Copy link

replied Jun 17, 2013

Maybe this commit message should be added to the build instructions in the README?

@adammw

This comment has been minimized.

Copy link

replied Jun 19, 2013

I question the need to have the android-configure script in node - it only works in a limited scenario where the NDK is installled but the toolchain isn't, and where bash is available. It also assumes that you want to build the toolchain in the current directory. All the other settings like AR, CC, CXX and LINK have to be set by anyone who is cross-compiling - adding one script to satisfy one platform and toolchain could lead to having to add scripts for every platform and toolchain.

That being said, I (personally) would like if configure had a --host parameter (that's the right one according to this blog post) which automatically prepends the AR, CC, CXX and LINK automatically based on the tuple/prefix, so at least scripts like these would be simpler with no need for endless exports as long as the prefixed tools are in the PATH.
(ie. ./configure --host=arm-linux-androideabi --without-snapshot)

@Mithgol

This comment has been minimized.

Copy link

replied Jun 19, 2013

Maybe this commit message should be added to the build instructions in the README?

A good idea.

It also could be added to https://github.com/joyent/node/wiki/Installation where all the other building steps are.

I also feel that the whole “Node on Android” thing is underdocumented (or, in more precise and general sense, lacks information).

  • Is someone going to make and distribute regular builds of Node for Android? (Some node.apk files?)
  • How does Node behave on Android?
    • How do I get a REPL console out of it? (Does Android even have any concept of console applications?)
    • How do I run a JavaScript in a console and view its output? Is it possible to associate Node on Android with .js files so that their shortcuts are run from Android's desktop as applications?
    • Should an Android device be rooted to run Node?
    • Could a Node-running JavaScript act as a continuously running Android service? (Such as scripts running with https://github.com/coreybutler/node-windows on Windows, with https://github.com/coreybutler/node-linux on Linux, with https://github.com/coreybutler/node-mac on Mac.)
@bnoordhuis

This comment has been minimized.

Copy link
Member

replied Jun 19, 2013

Maybe this commit message should be added to the build instructions in the README?

Good idea. I'll add it once the kinks are ironed out.

Is someone going to make and distribute regular builds of Node for Android? (Some node.apk files?)

Maybe but it won't be us. Android is not an officially supported platform (yet - maybe in the future.)

@andythecoderman

This comment has been minimized.

Copy link

replied Jun 19, 2013

I'm pretty excited about node on android. I just started playing around with the nodecopter and would love to run my programs without having to lug my laptop around.

@Buggaboo

This comment has been minimized.

Copy link

replied Sep 18, 2015

I got node/io running as a shared_library on non-rooted android, baked into a repl app. I'm working towards a v4.0.0.0-rc merge.

I aim to release with:

  1. unix domain sockets, fs-based or abstract (done... with issues);
  2. sensors streaming through the aforementioned sockets (done... with issues)
  3. logcat (done);
  4. remote repl over http etc. (done)
  5. in-app repl (WiP)

Stay tuned.

Please sign in to comment.
You can’t perform that action at this time.