| // Copyright 2015 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. |
| |
| :doctype: article |
| |
| = Developing Crashpad |
| |
| == Status |
| |
| link:status.html[Project status] information has moved to its own page. |
| |
| == Introduction |
| |
| Crashpad is a https://dev.chromium.org/Home[Chromium project]. Most of |
| its development practices follow Chromium’s. In order to function on its |
| own in other projects, Crashpad uses |
| https://chromium.googlesource.com/chromium/mini_chromium/[mini_chromium], |
| a small, self-contained library that provides many of Chromium’s useful |
| low-level base routines. |
| https://chromium.googlesource.com/chromium/mini_chromium/+/master/README[mini_chromium’s |
| README] provides more detail. |
| |
| == Prerequisites |
| |
| To develop Crashpad, the following tools are necessary, and must be |
| present in the `$PATH` environment variable: |
| |
| * Chromium’s |
| https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. |
| * https://git-scm.com/[Git]. This is provided by Xcode on Mac OS X and by |
| depot_tools on Windows. |
| * https://www.python.org/[Python]. This is provided by the operating system on |
| Mac OS X, and by depot_tools on Windows. |
| * Appropriate development tools. For Mac OS X, this is |
| https://developer.apple.com/xcode/[Xcode], and for Windows, it’s |
| https://www.visualstudio.com/[Visual Studio]. |
| |
| == Getting the Source Code |
| |
| The main source code repository is a Git repository hosted at |
| https://chromium.googlesource.com/crashpad/crashpad. Although it is possible to |
| check out this repository directly with `git clone`, Crashpad’s dependencies are |
| managed by |
| https://dev.chromium.org/developers/how-tos/depottools#TOC-gclient[`gclient`] |
| instead of Git submodules, so to work on Crashpad, it is best to use `fetch` to |
| get the source code. |
| |
| `fetch` and `gclient` are part of the |
| https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. There’s no |
| need to install them separately. |
| |
| === Initial Checkout |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *mkdir \~/crashpad* |
| $ *cd ~/crashpad* |
| $ *fetch crashpad* |
| ---- |
| |
| `fetch crashpad` performs the initial `git clone` and `gclient sync`, |
| establishing a fully-functional local checkout. |
| |
| === Subsequent Checkouts |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~/crashpad/crashpad* |
| $ *git pull -r* |
| $ *gclient sync* |
| ---- |
| |
| == Building |
| |
| Crashpad uses https://gyp.gsrc.io/[GYP] to generate |
| https://ninja-build.org/[Ninja] build files. The build is described by `.gyp` |
| files throughout the Crashpad source code tree. The `build/gyp_crashpad.py` |
| script runs GYP properly for Crashpad, and is also called when you run `fetch |
| crashpad`, `gclient sync`, or `gclient runhooks`. |
| |
| The Ninja build files and build output are in the `out` directory. Both debug- |
| and release-mode configurations are available. The examples below show the debug |
| configuration. To build and test the release configuration, substitute `Release` |
| for `Debug`. |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~/crashpad/crashpad* |
| $ *ninja -C out/Debug* |
| ---- |
| |
| Ninja is part of the |
| https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. There’s no |
| need to install it separately. |
| |
| === Android |
| |
| Crashpad’s Android port is in its early stages. This build relies on |
| cross-compilation. It’s possible to develop Crashpad for Android on any platform |
| that the https://developer.android.com/ndk/[Android NDK (Native Development |
| Kit)] runs on. |
| |
| If it’s not already present on your system, |
| https://developer.android.com/ndk/downloads/[download the NDK package for your |
| system] and expand it to a suitable location. These instructions assume that |
| it’s been expanded to `~/android-ndk-r13`. |
| |
| To build Crashpad, portions of the NDK must be reassembled into a |
| https://developer.android.com/ndk/guides/standalone_toolchain.html[standalone |
| toolchain]. This is a repackaged subset of the NDK suitable for cross-compiling |
| for a single Android architecture (such as `arm`, `arm64`, `x86`, and `x86_64`) |
| targeting a specific |
| https://source.android.com/source/build-numbers.html[Android API level]. The |
| standalone toolchain only needs to be built from the NDK one time for each set |
| of options desired. To build a standalone toolchain targeting 64-bit ARM and API |
| level 21 (Android 5.0 “Lollipop”), run: |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~* |
| $ *python android-ndk-r13/build/tools/make_standalone_toolchain.py \ |
| --arch=arm64 --api=21 --install-dir=android-ndk-r13_arm64_api21* |
| ---- |
| |
| Note that Chrome uses Android API level 21 for 64-bit platforms and 16 for |
| 32-bit platforms. See Chrome’s |
| https://chromium.googlesource.com/chromium/src/+/master/build/config/android/config.gni[`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. |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd \~/crashpad/crashpad* |
| $ *CC_target=\~/android-ndk-r13_arm64_api21/bin/clang \ |
| CXX_target=\~/android-ndk-r13_arm64_api21/bin/clang++ \ |
| AR_target=\~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-ar \ |
| NM_target=\~/android-ndk-r13_arm64_api21/bin/aarch64-linux-android-nm \ |
| READELF_target=~/android-ndk-r13_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* |
| ---- |
| |
| Target “triplets” to use for `ar`, `nm`, and `readelf` are: |
| |
| [width="40%",cols="1,3",frame="topbot"] |
| |=== |
| |`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. |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *ninja -C out_android_arm64_api21/out/Debug crashpad_test_test* |
| ---- |
| |
| == Testing |
| |
| Crashpad uses https://github.com/google/googletest/[Google Test] as its |
| unit-testing framework, and some tests use |
| https://github.com/google/googletest/tree/master/googlemock/[Google Mock] as |
| well. Its tests are currently split up into several test executables, each |
| dedicated to testing a different component. This may change in the future. After |
| a successful build, the test executables will be found at |
| `out/Debug/crashpad_*_test`. |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~/crashpad/crashpad* |
| $ *out/Debug/crashpad_minidump_test* |
| $ *out/Debug/crashpad_util_test* |
| ---- |
| |
| A script is provided to run all of Crashpad’s tests. It accepts a single |
| argument that tells it which configuration to test. |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~/crashpad/crashpad* |
| $ *python build/run_tests.py Debug* |
| ---- |
| |
| === Android |
| |
| To test on Android, use |
| https://developer.android.com/studio/command-line/adb.html[ADB (Android Debug |
| Bridge)] to `adb push` test executables and test data to a device or emulator, |
| then use `adb shell` to get a shell to run the test executables from. ADB is |
| part of the https://developer.android.com/sdk/[Android SDK]. Note that it is |
| sufficient to install just the command-line tools. The entire Android Studio IDE |
| is not necessary to obtain ADB. |
| |
| This example runs `crashpad_test_test` on a device. This test executable has a |
| run-time dependency on a second executable and a test data file, which are also |
| transferred to the device prior to running the test. |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~/crashpad/crashpad* |
| $ *adb push out_android_arm64_api21/out/Debug/crashpad_test_test /data/local/tmp/* |
| [100%] /data/local/tmp/crashpad_test_test |
| $ *adb push \ |
| out_android_arm64_api21/out/Debug/crashpad_test_test_multiprocess_exec_test_child \ |
| /data/local/tmp/* |
| [100%] /data/local/tmp/crashpad_test_test_multiprocess_exec_test_child |
| $ *adb shell mkdir -p /data/local/tmp/crashpad_test_data_root/test* |
| $ *adb push test/paths_test_data_root.txt \ |
| /data/local/tmp/crashpad_test_data_root/test/* |
| [100%] /data/local/tmp/crashpad_test_data_root/test/paths_test_data_root.txt |
| $ *adb shell* |
| device:/ $ *cd /data/local/tmp* |
| device:/data/local/tmp $ *CRASHPAD_TEST_DATA_ROOT=crashpad_test_data_root \ |
| ./crashpad_test_test* |
| ---- |
| |
| == Contributing |
| |
| Crashpad’s contribution process is very similar to |
| https://dev.chromium.org/developers/contributing-code[Chromium’s contribution |
| process]. |
| |
| === Code Review |
| |
| A code review must be conducted for every change to Crashpad’s source code. Code |
| review is conducted on https://chromium-review.googlesource.com/[Chromium’s |
| Gerrit] system, and all code reviews must be sent to an appropriate reviewer, |
| with a Cc sent to |
| https://groups.google.com/a/chromium.org/group/crashpad-dev[crashpad-dev]. The |
| https://chromium.googlesource.com/crashpad/crashpad/+/master/codereview.settings[`codereview.settings`] |
| file specifies this environment to `git-cl`. |
| |
| `git-cl` is part of the |
| https://dev.chromium.org/developers/how-tos/depottools[depot_tools]. There’s no |
| need to install it separately. |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~/crashpad/crashpad* |
| $ *git checkout -b work_branch origin/master* |
| _…do some work…_ |
| $ *git add …* |
| $ *git commit* |
| $ *git cl upload* |
| ---- |
| |
| The https://polygerrit.appspot.com/[PolyGerrit interface] to Gerrit, undergoing |
| active development, is recommended. To switch from the classic GWT-based Gerrit |
| UI to PolyGerrit, click the PolyGerrit link in a Gerrit review page’s footer. |
| |
| Uploading a patch to Gerrit does not automatically request a review. You must |
| select a reviewer on the Gerrit review page after running `git cl upload`. This |
| action notifies your reviewer of the code review request. If you have lost track |
| of the review page, `git cl issue` will remind you of its URL. Alternatively, |
| you can request review when uploading to Gerrit by using `git cl upload |
| --send-mail`. |
| |
| Git branches maintain their association with Gerrit reviews, so if you need to |
| make changes based on review feedback, you can do so on the correct Git branch, |
| committing your changes locally with `git commit`. You can then upload a new |
| patch set with `git cl upload` and let your reviewer know you’ve addressed the |
| feedback. |
| |
| === Landing Changes |
| |
| After code review is complete and “Code-Review: +1” has been received from all |
| reviewers, project members can commit the patch themselves: |
| |
| [subs="verbatim,quotes"] |
| ---- |
| $ *cd ~/crashpad/crashpad* |
| $ *git checkout work_branch* |
| $ *git cl land* |
| ---- |
| |
| Alternatively, patches can be committed by clicking the “Submit” button in the |
| Gerrit UI. |
| |
| Crashpad does not currently have a |
| https://dev.chromium.org/developers/testing/commit-queue[commit queue], so |
| contributors who are not project members will have to ask a project member to |
| commit the patch for them. Project members can commit changes on behalf of |
| external contributors by clicking the “Submit” button in the Gerrit UI. |
| |
| === External Contributions |
| |
| Copyright holders must complete the |
| https://developers.google.com/open-source/cla/individual[Individual Contributor |
| License Agreement] or |
| https://developers.google.com/open-source/cla/corporate[Corporate Contributor |
| License Agreement] as appropriate before any submission can be accepted, and |
| must be listed in the `AUTHORS` file. Contributors may be listed in the |
| `CONTRIBUTORS` file. |
| |
| == Buildbot |
| |
| The https://build.chromium.org/p/client.crashpad/[Crashpad Buildbot] performs |
| automated builds and tests of Crashpad. Before checking out or updating the |
| Crashpad source code, and after checking in a new change, it is prudent to check |
| the Buildbot to ensure that “the tree is green.” |