diff --git a/build/gyp_crashpad.py b/build/gyp_crashpad.py index fe9da840..dd5fa69c 100755 --- a/build/gyp_crashpad.py +++ b/build/gyp_crashpad.py @@ -75,11 +75,24 @@ def main(args): return result if sys.platform == 'win32': - # Also generate the x86 build. - result = gyp.main(args + ['-D', 'target_arch=ia32', '-G', 'config=Debug']) - if result != 0: - return result - result = gyp.main(args + ['-D', 'target_arch=ia32', '-G', 'config=Release']) + # Check to make sure that no target_arch was specified. target_arch may be + # set during a cross build, such as a cross build for Android. + has_target_arch = False + for arg_index in xrange(0, len(args)): + arg = args[arg_index] + if (arg.startswith('-Dtarget_arch=') or + (arg == '-D' and arg_index + 1 < len(args) and + args[arg_index + 1].startswith('target_arch='))): + has_target_arch = True + break + + if not has_target_arch: + # Also generate the x86 build. + result = gyp.main(args + ['-D', 'target_arch=ia32', '-G', 'config=Debug']) + if result != 0: + return result + result = gyp.main( + args + ['-D', 'target_arch=ia32', '-G', 'config=Release']) return result diff --git a/build/gyp_crashpad_android.py b/build/gyp_crashpad_android.py new file mode 100755 index 00000000..852839aa --- /dev/null +++ b/build/gyp_crashpad_android.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +# Copyright 2017 The Crashpad Authors. All rights reserved. +# +# 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 the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import glob +import gyp_crashpad +import os +import subprocess +import sys + + +def main(args): + parser = argparse.ArgumentParser( + description='Set up an Android cross build', + epilog='Additional arguments will be passed to gyp_crashpad.py.') + parser.add_argument('--ndk', required=True, help='Standalone NDK toolchain') + parser.add_argument('--compiler', + default='clang', + choices=('clang', 'gcc'), + help='The compiler to use, clang by default') + (parsed, extra_args) = parser.parse_known_args(args) + + NDK_ERROR=( + 'NDK must be a valid standalone NDK toolchain.\n' + + 'See https://developer.android.com/ndk/guides/standalone_toolchain.html') + arch_dirs = glob.glob(os.path.join(parsed.ndk, '*-linux-android*')) + if len(arch_dirs) != 1: + parser.error(NDK_ERROR) + + arch_triplet = os.path.basename(arch_dirs[0]) + ARCH_TRIPLET_TO_ARCH = { + 'arm-linux-androideabi': 'arm', + 'aarch64-linux-android': 'arm64', + 'i686-linux-android': 'x86', + 'x86_64-linux-android': 'x86_64', + 'mipsel-linux-android': 'mips', + 'mips64el-linux-android': 'mips64', + } + if arch_triplet not in ARCH_TRIPLET_TO_ARCH: + parser.error(NDK_ERROR) + arch = ARCH_TRIPLET_TO_ARCH[arch_triplet] + + ndk_bin_dir = os.path.join(parsed.ndk, 'bin') + + if parsed.compiler == 'clang': + os.environ['CC_target'] = os.path.join(ndk_bin_dir, 'clang') + os.environ['CXX_target'] = os.path.join(ndk_bin_dir, 'clang++') + elif parsed.compiler == 'gcc': + os.environ['CC_target'] = os.path.join(ndk_bin_dir, + '%s-gcc' % arch_triplet) + os.environ['CXX_target'] = os.path.join(ndk_bin_dir, + '%s-g++' % arch_triplet) + + for tool in ('ar', 'nm', 'readelf'): + os.environ['%s_target' % tool.upper()] = ( + os.path.join(ndk_bin_dir, '%s-%s' % (arch_triplet, tool))) + + return gyp_crashpad.main( + ['-D', 'OS=android', + '-D', 'target_arch=%s' % arch, + '-D', 'clang=%d' % (1 if parsed.compiler == 'clang' else 0), + '-f', 'ninja-android'] + extra_args) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/doc/developing.md b/doc/developing.md index 9beec52c..65d62356 100644 --- a/doc/developing.md +++ b/doc/developing.md @@ -137,46 +137,35 @@ Note that Chrome uses Android API level 21 for 64-bit platforms and 16 for [`build/config/android/config.gni`](https://chromium.googlesource.com/chromium/src/+/master/build/config/android/config.gni) which sets `_android_api_level` and `_android64_api_level`. -To configure a Crashpad build for Android using this standalone toolchain, set -several environment variables directing the build to the standalone toolchain, -along with GYP options to identify an Android build. This must be done after any -`gclient sync`, or instead of any `gclient runhooks` operation. The environment -variables only need to be set for this `gyp_crashpad.py` invocation, and need -not be permanent. +To configure a Crashpad build for Android using the standalone toolchain +assembled above, use `gyp_crashpad_android.py`. This script is a wrapper for +`gyp_crashpad.py` that sets several environment variables directing the build to +the standalone toolchain, and several GYP options to identify an Android build. +This must be done after any `gclient sync`, or instead of any `gclient runhooks` +operation. ``` $ cd ~/crashpad/crashpad -$ CC_target=~/android-ndk-r14_arm64_api21/bin/clang \ - CXX_target=~/android-ndk-r14_arm64_api21/bin/clang++ \ - AR_target=~/android-ndk-r14_arm64_api21/bin/aarch64-linux-android-ar \ - NM_target=~/android-ndk-r14_arm64_api21/bin/aarch64-linux-android-nm \ - READELF_target=~/android-ndk-r14_arm64_api21/bin/aarch64-linux-android-readelf \ - python build/gyp_crashpad.py \ - -DOS=android -Dtarget_arch=arm64 -Dclang=1 \ - --generator-output=out/android_arm64_api21 -f ninja-android +$ python build/gyp_crashpad_android.py \ + --ndk ~/android-ndk-r14_arm64_api21 \ + --generator-output out/android_arm64_api21 ``` -It is also possible to use GCC instead of Clang by making the appropriate -substitutions: `aarch64-linux-android-gcc` for `CC_target`; -`aarch64-linux-android-g++` for `CXX_target`; and `-Dclang=0` as an argument to -`gyp_crashpad.py`. +`gyp_crashpad_android.py` detects the build type based on the characteristics of +the standalone toolchain given in its `--ndk` argument. -Target “triplets” to use for `ar`, `nm`, `readelf`, `gcc`, and `g++` are: +`gyp_crashpad_android.py` sets the build up to use Clang by default. It’s also +possible to use GCC by providing the `--compiler=gcc` argument to +`gyp_crashpad_android.py`. -| Architecture | Target “triplet” | -|:-------------|:------------------------| -| `arm` | `arm-linux-androideabi` | -| `arm64` | `aarch64-linux-android` | -| `x86` | `i686-linux-android` | -| `x86_64` | `x86_64-linux-android` | - -The port is incomplete, but targets known to be working include `crashpad_util`, -`crashpad_test`, and `crashpad_test_test`. This list will grow over time. To -build, direct `ninja` to the specific `out` directory chosen by -`--generator-output` above. +The Android port is incomplete, but targets known to be working include +`crashpad_test`, `crashpad_util`, and their tests. This list will grow over +time. To build, direct `ninja` to the specific `out` directory chosen by the +`--generator-output` argument to `gyp_crashpad_android.py`. ``` -$ ninja -C out/android_arm64_api21/out/Debug crashpad_test_test +$ ninja -C out/android_arm64_api21/out/Debug \ + crashpad_test_test crashpad_util_test ``` ## Testing