Add Android cross-compilation support to top-level Makefile
authorjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 16 Jan 2012 13:29:12 +0000 (13:29 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 16 Jan 2012 13:29:12 +0000 (13:29 +0000)
TEST=make android

Review URL: http://codereview.chromium.org/9179009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10409 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

Makefile
build/android.gypi [new file with mode: 0644]
build/common.gypi
src/d8.gyp
src/platform-linux.cc

index 09d1e8b..833c875 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# Copyright 2011 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
@@ -33,6 +33,8 @@ OUTDIR ?= out
 TESTJOBS ?= -j16
 GYPFLAGS ?=
 TESTFLAGS ?=
+ANDROID_NDK_ROOT ?=
+ANDROID_TOOL_PREFIX = $(ANDROID_NDK_ROOT)/toolchain/bin/arm-linux-androideabi
 
 # Special build flags. Use them like this: "make library=shared"
 
@@ -93,6 +95,7 @@ endif
 # - every combination <arch>.<mode>, e.g. "ia32.release"
 # - "native": current host's architecture, release mode
 # - any of the above with .check appended, e.g. "ia32.release.check"
+# - "android": cross-compile for Android/ARM (release mode)
 # - default (no target specified): build all DEFAULT_ARCHES and MODES
 # - "check": build all targets and run all tests
 # - "<arch>.clean" for any <arch> in ARCHES
@@ -120,7 +123,8 @@ ENVFILE = $(OUTDIR)/environment
 
 .PHONY: all check clean dependencies $(ENVFILE).new native \
         $(ARCHES) $(MODES) $(BUILDS) $(CHECKS) $(addsuffix .clean,$(ARCHES)) \
-        $(addsuffix .check,$(MODES)) $(addsuffix .check,$(ARCHES))
+        $(addsuffix .check,$(MODES)) $(addsuffix .check,$(ARCHES)) \
+        must-set-ANDROID_NDK_ROOT
 
 # Target definitions. "all" is the default.
 all: $(MODES)
@@ -144,6 +148,18 @@ native: $(OUTDIR)/Makefile-native
                 CXX="$(CXX)" LINK="$(LINK)" BUILDTYPE=Release \
                 builddir="$(shell pwd)/$(OUTDIR)/$@"
 
+# TODO(jkummerow): add "android.debug" when we need it.
+android android.release: $(OUTDIR)/Makefile-android
+       @$(MAKE) -C "$(OUTDIR)" -f Makefile-android \
+               CXX="$(ANDROID_TOOL_PREFIX)-g++" \
+               AR="$(ANDROID_TOOL_PREFIX)-ar" \
+               RANLIB="$(ANDROID_TOOL_PREFIX)-ranlib" \
+               CC="$(ANDROID_TOOL_PREFIX)-gcc" \
+               LD="$(ANDROID_TOOL_PREFIX)-ld" \
+               LINK="$(ANDROID_TOOL_PREFIX)-g++" \
+               BUILDTYPE=Release \
+               builddir="$(shell pwd)/$(OUTDIR)/android.release"
+
 # Test targets.
 check: all
        @tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
@@ -178,6 +194,11 @@ native.clean:
        rm -rf $(OUTDIR)/native
        find $(OUTDIR) -regex '.*\(host\|target\)-native\.mk' -delete
 
+android.clean:
+       rm -f $(OUTDIR)/Makefile-android
+       rm -rf $(OUTDIR)/android.release
+       find $(OUTDIR) -regex '.*\(host\|target\)-android\.mk' -delete
+
 clean: $(addsuffix .clean,$(ARCHES)) native.clean
 
 # GYP file generation targets.
@@ -205,6 +226,18 @@ $(OUTDIR)/Makefile-native: $(GYPFILES) $(ENVFILE)
        build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
                      -Ibuild/standalone.gypi --depth=. -S-native $(GYPFLAGS)
 
+$(OUTDIR)/Makefile-android: $(GYPFILES) $(ENVFILE) build/android.gypi \
+                            must-set-ANDROID_NDK_ROOT
+       CC="${ANDROID_TOOL_PREFIX}-gcc" \
+       build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
+                     -Ibuild/standalone.gypi --depth=. -Ibuild/android.gypi \
+                     -S-android $(GYPFLAGS)
+
+must-set-ANDROID_NDK_ROOT:
+ifndef ANDROID_NDK_ROOT
+         $(error ANDROID_NDK_ROOT is not set)
+endif
+
 # Replaces the old with the new environment file if they're different, which
 # will trigger GYP to regenerate Makefiles.
 $(ENVFILE): $(ENVFILE).new
diff --git a/build/android.gypi b/build/android.gypi
new file mode 100644 (file)
index 0000000..ffd0648
--- /dev/null
@@ -0,0 +1,225 @@
+# Copyright 2012 the V8 project authors. 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 Google Inc. 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
+# OWNER 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.
+
+# Definitions for building standalone V8 binaries to run on Android.
+# This is mostly excerpted from:
+# http://src.chromium.org/viewvc/chrome/trunk/src/build/common.gypi
+
+{
+  'variables': {
+    # Location of Android NDK.
+    'variables': {
+      'variables': {
+        'android_ndk_root%': '<!(/bin/echo -n $ANDROID_NDK_ROOT)',
+        'android_target_arch%': 'arm',  # target_arch in android terms.
+
+        # Switch between different build types, currently only '0' is
+        # supported.
+        'android_build_type%': 0,
+      },
+      'android_ndk_root%': '<(android_ndk_root)',
+      'android_ndk_sysroot': '<(android_ndk_root)/platforms/android-9/arch-<(android_target_arch)',
+      'android_build_type%': '<(android_build_type)',
+    },
+    'android_ndk_root%': '<(android_ndk_root)',
+    'android_ndk_sysroot': '<(android_ndk_sysroot)',
+    'android_ndk_include': '<(android_ndk_sysroot)/usr/include',
+    'android_ndk_lib': '<(android_ndk_sysroot)/usr/lib',
+    # Enable to use the system stlport, otherwise statically
+    # link the NDK one?
+    'use_system_stlport%': '<(android_build_type)',
+    'android_stlport_library': 'stlport_static',
+    # Copy it out one scope.
+    'android_build_type%': '<(android_build_type)',
+
+    'OS': 'android',
+    'target_arch': 'arm',
+    'v8_target_arch': 'arm',
+    'armv7': 1,
+    'arm_neon': 0,
+    'arm_fpu': 'vfpv3',
+  },  # variables
+  'target_defaults': {
+    'defines': [
+      'ANDROID',
+      'V8_ANDROID_LOG_STDOUT',
+    ],
+    'configurations': {
+      'Release': {
+        'cflags!': [
+          '-O2',
+          '-Os',
+        ],
+        'cflags': [
+          '-fdata-sections',
+          '-ffunction-sections',
+          '-fomit-frame-pointer',
+          '-O3',
+        ],
+      },  # Release
+    },  # configurations
+    'cflags': [ '-Wno-abi', '-Wall', '-W', '-Wno-unused-parameter',
+                '-Wnon-virtual-dtor', '-fno-rtti', '-fno-exceptions', ],
+    'target_conditions': [
+      ['_toolset=="target"', {
+        'cflags!': [
+          '-pthread',  # Not supported by Android toolchain.
+        ],
+        'cflags': [
+          '-U__linux__',  # Don't allow toolchain to claim -D__linux__
+          '-ffunction-sections',
+          '-funwind-tables',
+          '-fstack-protector',
+          '-fno-short-enums',
+          '-finline-limit=64',
+          '-Wa,--noexecstack',
+          '-Wno-error=non-virtual-dtor',  # TODO(michaelbai): Fix warnings.
+          # Note: This include is in cflags to ensure that it comes after
+          # all of the includes.
+          '-I<(android_ndk_include)',
+          '-march=armv7-a',
+          '-mtune=cortex-a8',
+          '-mfpu=vfp3',
+        ],
+        'defines': [
+          'ANDROID',
+          #'__GNU_SOURCE=1',  # Necessary for clone()
+          'USE_STLPORT=1',
+          '_STLP_USE_PTR_SPECIALIZATIONS=1',
+          'HAVE_OFF64_T',
+          'HAVE_SYS_UIO_H',
+          'ANDROID_BINSIZE_HACK', # Enable temporary hacks to reduce binsize.
+        ],
+        'ldflags!': [
+          '-pthread',  # Not supported by Android toolchain.
+        ],
+        'ldflags': [
+          '-nostdlib',
+          '-Wl,--no-undefined',
+          '-Wl,--icf=safe',  # Enable identical code folding to reduce size
+          # Don't export symbols from statically linked libraries.
+          '-Wl,--exclude-libs=ALL',
+        ],
+        'libraries!': [
+            '-lrt',  # librt is built into Bionic.
+            # Not supported by Android toolchain.
+            # Where do these come from?  Can't find references in
+            # any Chromium gyp or gypi file.  Maybe they come from
+            # gyp itself?
+            '-lpthread', '-lnss3', '-lnssutil3', '-lsmime3', '-lplds4', '-lplc4', '-lnspr4',
+          ],
+          'libraries': [
+            '-l<(android_stlport_library)',
+            # Manually link the libgcc.a that the cross compiler uses.
+            '<!($CC -print-libgcc-file-name)',
+            '-lc',
+            '-ldl',
+            '-lstdc++',
+            '-lm',
+        ],
+        'conditions': [
+          ['android_build_type==0', {
+            'ldflags': [
+              '-Wl,-rpath-link=<(android_ndk_lib)',
+              '-L<(android_ndk_lib)',
+            ],
+          }],
+          # NOTE: The stlport header include paths below are specified in
+          # cflags rather than include_dirs because they need to come
+          # after include_dirs. Think of them like system headers, but
+          # don't use '-isystem' because the arm-linux-androideabi-4.4.3
+          # toolchain (circa Gingerbread) will exhibit strange errors.
+          # The include ordering here is important; change with caution.
+          ['use_system_stlport==0', {
+            'cflags': [
+              '-I<(android_ndk_root)/sources/cxx-stl/stlport/stlport',
+            ],
+            'conditions': [
+              ['target_arch=="arm" and armv7==1', {
+                'ldflags': [
+                  '-L<(android_ndk_root)/sources/cxx-stl/stlport/libs/armeabi-v7a',
+                ],
+              }],
+              ['target_arch=="arm" and armv7==0', {
+                'ldflags': [
+                  '-L<(android_ndk_root)/sources/cxx-stl/stlport/libs/armeabi',
+                ],
+              }],
+              ['target_arch=="ia32"', {
+                'ldflags': [
+                  '-L<(android_ndk_root)/sources/cxx-stl/stlport/libs/x86',
+                ],
+              }],
+            ],
+          }],
+          ['target_arch=="ia32"', {
+            # The x86 toolchain currently has problems with stack-protector.
+            'cflags!': [
+              '-fstack-protector',
+            ],
+            'cflags': [
+              '-fno-stack-protector',
+            ],
+          }],
+        ],
+        'target_conditions': [
+          ['_type=="executable"', {
+            'ldflags': [
+              '-Bdynamic',
+              '-Wl,-dynamic-linker,/system/bin/linker',
+              '-Wl,--gc-sections',
+              '-Wl,-z,nocopyreloc',
+              # crtbegin_dynamic.o should be the last item in ldflags.
+              '<(android_ndk_lib)/crtbegin_dynamic.o',
+            ],
+            'libraries': [
+              # crtend_android.o needs to be the last item in libraries.
+              # Do not add any libraries after this!
+              '<(android_ndk_lib)/crtend_android.o',
+            ],
+          }],
+          ['_type=="shared_library"', {
+            'ldflags': [
+              '-Wl,-shared,-Bsymbolic',
+            ],
+          }],
+        ],
+      }],  # _toolset=="target"
+      # Settings for building host targets using the system toolchain.
+      ['_toolset=="host"', {
+        'cflags': [ '-m32', '-pthread' ],
+        'ldflags': [ '-m32', '-pthread' ],
+        'ldflags!': [
+          '-Wl,-z,noexecstack',
+          '-Wl,--gc-sections',
+          '-Wl,-O1',
+          '-Wl,--as-needed',
+        ],
+      }],
+    ],  # target_conditions
+  },  # target_defaults
+}
\ No newline at end of file
index 7aab913..cd8d98e 100644 (file)
       },
       'Release': {
         'conditions': [
-          ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
+          ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" \
+            or OS=="android"', {
             'cflags!': [
               '-O2',
               '-Os',
index a096af3..3b92d03 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2010 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are
 # met:
index 68670e0..5a1c0d1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -1151,6 +1151,9 @@ class SignalSender : public Thread {
     // occuring during signal delivery.
     useconds_t interval = interval_ * 1000 - 100;
     if (full_or_half == HALF_INTERVAL) interval /= 2;
+#if defined(ANDROID)
+    usleep(interval);
+#else
     int result = usleep(interval);
 #ifdef DEBUG
     if (result != 0 && errno != EINTR) {
@@ -1160,8 +1163,9 @@ class SignalSender : public Thread {
               errno);
       ASSERT(result == 0 || errno == EINTR);
     }
-#endif
+#endif  // DEBUG
     USE(result);
+#endif  // ANDROID
   }
 
   const int vm_tgid_;