Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
build: add android support
Browse files Browse the repository at this point in the history
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 Jun 17, 2013
1 parent ffcd8b9 commit 5e4e8ec
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 17 deletions.
19 changes: 19 additions & 0 deletions android-configure
Original file line number Diff line number Diff line change
@@ -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
14 changes: 11 additions & 3 deletions common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -187,6 +191,10 @@
}],
],
}],
[ 'OS=="android"', {
'defines': ['_GLIBCXX_USE_C99_MATH'],
'libraries': [ '-llog' ],
}],
['OS=="mac"', {
'defines': ['_DARWIN_USE_64_BIT_INODE=1'],
'xcode_settings': {
Expand Down
5 changes: 4 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 '')
Expand Down Expand Up @@ -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']
Expand Down
21 changes: 14 additions & 7 deletions doc/api/process.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/cares_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
10 changes: 5 additions & 5 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down

6 comments on commit 5e4e8ec

@ry
Copy link

@ry ry commented on 5e4e8ec Jun 17, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@adammw
Copy link

@adammw adammw commented on 5e4e8ec Jun 19, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@bnoordhuis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.