android: Add gyp_crashpad_android.py for easier Android development

Bug: crashpad:30
Change-Id: Idf7e6db944bf946e6571064306897848222cd36f
Reviewed-on: https://chromium-review.googlesource.com/458078
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Mark Mentovai 2017-03-22 17:34:54 -04:00
parent cca10659c7
commit db8c54e142
3 changed files with 117 additions and 36 deletions

View File

@ -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

79
build/gyp_crashpad_android.py Executable file
View File

@ -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:]))

View File

@ -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. Its 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