0
0
mirror of https://github.com/chromium/crashpad.git synced 2025-03-28 04:30:12 +00:00
2016-11-01 15:01:22 -04:00

1095 lines
34 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.9">
<title>Developing Crashpad</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
/* Default font. */
body {
font-family: Georgia,serif;
}
/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
font-family: Arial,Helvetica,sans-serif;
}
body {
margin: 1em 5% 1em 5%;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: fuchsia;
}
em {
font-style: italic;
color: navy;
}
strong {
font-weight: bold;
color: #083194;
}
h1, h2, h3, h4, h5, h6 {
color: #527bbd;
margin-top: 1.2em;
margin-bottom: 0.5em;
line-height: 1.3;
}
h1, h2, h3 {
border-bottom: 2px solid silver;
}
h2 {
padding-top: 0.5em;
}
h3 {
float: left;
}
h3 + * {
clear: left;
}
h5 {
font-size: 1.0em;
}
div.sectionbody {
margin-left: 0;
}
hr {
border: 1px solid silver;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
ul > li { color: #aaa; }
ul > li > * { color: black; }
.monospaced, code, pre {
font-family: "Courier New", Courier, monospace;
font-size: inherit;
color: navy;
padding: 0;
margin: 0;
}
pre {
white-space: pre-wrap;
}
#author {
color: #527bbd;
font-weight: bold;
font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}
#footer {
font-size: small;
border-top: 2px solid silver;
padding-top: 0.5em;
margin-top: 4.0em;
}
#footer-text {
float: left;
padding-bottom: 0.5em;
}
#footer-badges {
float: right;
padding-bottom: 0.5em;
}
#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.0em;
margin-bottom: 2.0em;
margin-right: 10%;
color: #606060;
}
div.content { /* Block element content. */
padding: 0;
}
/* Block element titles. */
div.title, caption.title {
color: #527bbd;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid #dddddd;
border-left: 4px solid #f0f0f0;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid #dddddd;
border-left: 5px solid #f0f0f0;
background: #f8f8f8;
padding: 0.5em;
}
div.quoteblock, div.verseblock {
padding-left: 1.0em;
margin-left: 1.0em;
margin-right: 10%;
border-left: 5px solid #f0f0f0;
color: #888;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock > pre.content {
font-family: inherit;
font-size: inherit;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #527bbd;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 3px solid #dddddd;
}
div.exampleblock > div.content {
border-left: 3px solid #dddddd;
padding-left: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; vertical-align: text-bottom; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: navy;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: navy;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
.footnote, .footnoteref {
font-size: 0.8em;
}
span.footnote, span.footnoteref {
vertical-align: super;
}
#footnotes {
margin: 20px 0 20px 0;
padding: 7px 0 0 0;
}
#footnotes div.footnote {
margin: 0 0 5px 0;
}
#footnotes hr {
border: none;
border-top: 1px solid silver;
height: 1px;
text-align: left;
margin-left: 0;
width: 20%;
min-width: 100px;
}
div.colist td {
padding-right: 0.5em;
padding-bottom: 0.3em;
vertical-align: top;
}
div.colist td img {
margin-top: 0.3em;
}
@media print {
#footer-badges { display: none; }
}
#toc {
margin-bottom: 2.5em;
}
#toctitle {
color: #527bbd;
font-size: 1.1em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
margin-top: 0;
margin-bottom: 0;
}
div.toclevel2 {
margin-left: 2em;
font-size: 0.9em;
}
div.toclevel3 {
margin-left: 4em;
font-size: 0.9em;
}
div.toclevel4 {
margin-left: 6em;
font-size: 0.9em;
}
span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }
span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }
span.big { font-size: 2em; }
span.small { font-size: 0.6em; }
span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }
div.unbreakable { page-break-inside: avoid; }
/*
* xhtml11 specific
*
* */
div.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.tableblock > table {
border: 3px solid #527bbd;
}
thead, p.table.header {
font-weight: bold;
color: #527bbd;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
/*
* html5 specific
*
* */
table.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
thead, p.tableblock.header {
font-weight: bold;
color: #527bbd;
}
p.tableblock {
margin-top: 0;
}
table.tableblock {
border-width: 3px;
border-spacing: 0px;
border-style: solid;
border-color: #527bbd;
border-collapse: collapse;
}
th.tableblock, td.tableblock {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #527bbd;
}
table.tableblock.frame-topbot {
border-left-style: hidden;
border-right-style: hidden;
}
table.tableblock.frame-sides {
border-top-style: hidden;
border-bottom-style: hidden;
}
table.tableblock.frame-none {
border-style: hidden;
}
th.tableblock.halign-left, td.tableblock.halign-left {
text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
text-align: right;
}
th.tableblock.valign-top, td.tableblock.valign-top {
vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
vertical-align: bottom;
}
/*
* manpage specific
*
* */
body.manpage h1 {
padding-top: 0.5em;
padding-bottom: 0.5em;
border-top: 2px solid silver;
border-bottom: 2px solid silver;
}
body.manpage h2 {
border-style: none;
}
body.manpage div.sectionbody {
margin-left: 3em;
}
@media print {
body.manpage div#toc { display: none; }
}
/* 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. */
/* The default AsciiDoc asciidoc.css specifies fuchsia as the visited link
* color. This has a dated appearance. Replace it with blue, the same color used
* for unvisited links. */
a:visited {
color: blue;
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = { // Namespace.
/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////
/* Author: Mihai Bazon, September 2002
* http://students.infoiasi.ro/~mishoo
*
* Table Of Content generator
* Version: 0.4
*
* Feel free to use this script under the terms of the GNU General Public
* License, as long as you do not remove or alter this notice.
*/
/* modified by Troy D. Hanson, September 2006. License: GPL */
/* modified by Stuart Rackham, 2006, 2009. License: GPL */
// toclevels = 1..4.
toc: function (toclevels) {
function getText(el) {
var text = "";
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
text += i.data;
else if (i.firstChild != null)
text += getText(i);
}
return text;
}
function TocEntry(el, text, toclevel) {
this.element = el;
this.text = text;
this.toclevel = toclevel;
}
function tocEntries(el, toclevels) {
var result = new Array;
var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
// Function that scans the DOM tree for header elements (the DOM2
// nodeIterator API would be a better technique but not supported by all
// browsers).
var iterate = function (el) {
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
var mo = re.exec(i.tagName);
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
}
iterate(i);
}
}
}
iterate(el);
return result;
}
var toc = document.getElementById("toc");
if (!toc) {
return;
}
// Delete existing TOC entries in case we're reloading the TOC.
var tocEntriesToRemove = [];
var i;
for (i = 0; i < toc.childNodes.length; i++) {
var entry = toc.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div'
&& entry.getAttribute("class")
&& entry.getAttribute("class").match(/^toclevel/))
tocEntriesToRemove.push(entry);
}
for (i = 0; i < tocEntriesToRemove.length; i++) {
toc.removeChild(tocEntriesToRemove[i]);
}
// Rebuild TOC entries.
var entries = tocEntries(document.getElementById("content"), toclevels);
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (entry.element.id == "")
entry.element.id = "_toc_" + i;
var a = document.createElement("a");
a.href = "#" + entry.element.id;
a.appendChild(document.createTextNode(entry.text));
var div = document.createElement("div");
div.appendChild(a);
div.className = "toclevel" + entry.toclevel;
toc.appendChild(div);
}
if (entries.length == 0)
toc.parentNode.removeChild(toc);
},
/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////
/* Based on footnote generation code from:
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
*/
footnotes: function () {
// Delete existing footnote entries in case we're reloading the footnodes.
var i;
var noteholder = document.getElementById("footnotes");
if (!noteholder) {
return;
}
var entriesToRemove = [];
for (i = 0; i < noteholder.childNodes.length; i++) {
var entry = noteholder.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
entriesToRemove.push(entry);
}
for (i = 0; i < entriesToRemove.length; i++) {
noteholder.removeChild(entriesToRemove[i]);
}
// Rebuild footnote entries.
var cont = document.getElementById("content");
var spans = cont.getElementsByTagName("span");
var refs = {};
var n = 0;
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnote") {
n++;
var note = spans[i].getAttribute("data-note");
if (!note) {
// Use [\s\S] in place of . so multi-line matches work.
// Because JavaScript has no s (dotall) regex flag.
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
spans[i].innerHTML =
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
spans[i].setAttribute("data-note", note);
}
noteholder.innerHTML +=
"<div class='footnote' id='_footnote_" + n + "'>" +
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
n + "</a>. " + note + "</div>";
var id =spans[i].getAttribute("id");
if (id != null) refs["#"+id] = n;
}
}
if (n == 0)
noteholder.parentNode.removeChild(noteholder);
else {
// Process footnoterefs.
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnoteref") {
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
href = href.match(/#.*/)[0]; // Because IE return full URL.
n = refs[href];
spans[i].innerHTML =
"[<a href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
}
}
}
},
install: function(toclevels) {
var timerId;
function reinstall() {
asciidoc.footnotes();
if (toclevels) {
asciidoc.toc(toclevels);
}
}
function reinstallAndRemoveTimer() {
clearInterval(timerId);
reinstall();
}
timerId = setInterval(reinstall, 500);
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
else
window.onload = reinstallAndRemoveTimer;
}
}
asciidoc.install();
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>Developing Crashpad</h1>
</div>
<div id="content">
<div class="sect1">
<h2 id="_status">Status</h2>
<div class="sectionbody">
<div class="paragraph"><p><a href="status.html">Project status</a> information has moved to its own page.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_introduction">Introduction</h2>
<div class="sectionbody">
<div class="paragraph"><p>Crashpad is a <a href="https://dev.chromium.org/Home">Chromium project</a>. Most of
its development practices follow Chromiums. In order to function on its
own in other projects, Crashpad uses
<a href="https://chromium.googlesource.com/chromium/mini_chromium/">mini_chromium</a>,
a small, self-contained library that provides many of Chromiums useful
low-level base routines.
<a href="https://chromium.googlesource.com/chromium/mini_chromium/+/master/README">mini_chromiums
README</a> provides more detail.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_prerequisites">Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph"><p>To develop Crashpad, the following tools are necessary, and must be
present in the <span class="monospaced">$PATH</span> environment variable:</p></div>
<div class="ulist"><ul>
<li>
<p>
Chromiums
<a href="https://dev.chromium.org/developers/how-tos/depottools">depot_tools</a>.
</p>
</li>
<li>
<p>
<a href="https://git-scm.com/">Git</a>. This is provided by Xcode on Mac OS X and by
depot_tools on Windows.
</p>
</li>
<li>
<p>
<a href="https://www.python.org/">Python</a>. This is provided by the operating system on
Mac OS X, and by depot_tools on Windows.
</p>
</li>
<li>
<p>
Appropriate development tools. For Mac OS X, this is
<a href="https://developer.apple.com/xcode/">Xcode</a>, and for Windows, its
<a href="https://www.visualstudio.com/">Visual Studio</a>.
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_getting_the_source_code">Getting the Source Code</h2>
<div class="sectionbody">
<div class="paragraph"><p>The main source code repository is a Git repository hosted at
<a href="https://chromium.googlesource.com/crashpad/crashpad">https://chromium.googlesource.com/crashpad/crashpad</a>. Although it is possible to
check out this repository directly with <span class="monospaced">git clone</span>, Crashpads dependencies are
managed by
<a href="https://dev.chromium.org/developers/how-tos/depottools#TOC-gclient"><span class="monospaced">gclient</span></a>
instead of Git submodules, so to work on Crashpad, it is best to use <span class="monospaced">fetch</span> to
get the source code.</p></div>
<div class="paragraph"><p><span class="monospaced">fetch</span> and <span class="monospaced">gclient</span> are part of the
<a href="https://dev.chromium.org/developers/how-tos/depottools">depot_tools</a>. Theres no
need to install them separately.</p></div>
<div class="sect2">
<h3 id="_initial_checkout">Initial Checkout</h3>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>mkdir ~/crashpad</strong>
$ <strong>cd ~/crashpad</strong>
$ <strong>fetch crashpad</strong></pre>
</div></div>
<div class="paragraph"><p><span class="monospaced">fetch crashpad</span> performs the initial <span class="monospaced">git clone</span> and <span class="monospaced">gclient sync</span>,
establishing a fully-functional local checkout.</p></div>
</div>
<div class="sect2">
<h3 id="_subsequent_checkouts">Subsequent Checkouts</h3>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>git pull -r</strong>
$ <strong>gclient sync</strong></pre>
</div></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_building">Building</h2>
<div class="sectionbody">
<div class="paragraph"><p>Crashpad uses <a href="https://gyp.gsrc.io/">GYP</a> to generate
<a href="https://ninja-build.org/">Ninja</a> build files. The build is described by <span class="monospaced">.gyp</span>
files throughout the Crashpad source code tree. The <span class="monospaced">build/gyp_crashpad.py</span>
script runs GYP properly for Crashpad, and is also called when you run <span class="monospaced">fetch
crashpad</span>, <span class="monospaced">gclient sync</span>, or <span class="monospaced">gclient runhooks</span>.</p></div>
<div class="paragraph"><p>The Ninja build files and build output are in the <span class="monospaced">out</span> directory. Both debug-
and release-mode configurations are available. The examples below show the debug
configuration. To build and test the release configuration, substitute <span class="monospaced">Release</span>
for <span class="monospaced">Debug</span>.</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>ninja -C out/Debug</strong></pre>
</div></div>
<div class="paragraph"><p>Ninja is part of the
<a href="https://dev.chromium.org/developers/how-tos/depottools">depot_tools</a>. Theres no
need to install it separately.</p></div>
<div class="sect2">
<h3 id="_android">Android</h3>
<div class="paragraph"><p>Crashpads Android port is in its early stages. This build relies on
cross-compilation. Its possible to develop Crashpad for Android on any platform
that the <a href="https://developer.android.com/ndk/">Android NDK (Native Development
Kit)</a> runs on.</p></div>
<div class="paragraph"><p>If its not already present on your system,
<a href="https://developer.android.com/ndk/downloads/">download the NDK package for your
system</a> and expand it to a suitable location. These instructions assume that
its been expanded to <span class="monospaced">~/android-ndk-r13</span>.</p></div>
<div class="paragraph"><p>To build Crashpad, portions of the NDK must be reassembled into a
<a href="https://developer.android.com/ndk/guides/standalone_toolchain.html">standalone
toolchain</a>. This is a repackaged subset of the NDK suitable for cross-compiling
for a single Android architecture (such as <span class="monospaced">arm</span>, <span class="monospaced">arm64</span>, <span class="monospaced">x86</span>, and <span class="monospaced">x86_64</span>)
targeting a specific
<a href="https://source.android.com/source/build-numbers.html">Android API level</a>. 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:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~</strong>
$ <strong>python android-ndk-r13/build/tools/make_standalone_toolchain.py \
--arch=arm64 --api=21 --install-dir=android-ndk-r13_arm64_api21</strong></pre>
</div></div>
<div class="paragraph"><p>Note that Chrome uses Android API level 21 for 64-bit platforms and 16 for
32-bit platforms. See Chromes
<a href="https://chromium.googlesource.com/chromium/src/+/master/build/config/android/config.gni"><span class="monospaced">build/config/android/config.gni</span></a>
which sets <span class="monospaced">_android_api_level</span> and <span class="monospaced">_android64_api_level</span>.</p></div>
<div class="paragraph"><p>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 <span class="monospaced">gclient sync</span>, or instead of any <span class="monospaced">gclient runhooks</span> operation.
The environment variables only need to be set for this <span class="monospaced">gyp_crashpad.py</span>
invocation, and need not be permanent.</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>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</strong></pre>
</div></div>
<div class="paragraph"><p>Target “triplets” to use for <span class="monospaced">ar</span>, <span class="monospaced">nm</span>, and <span class="monospaced">readelf</span> are:</p></div>
<table class="tableblock frame-topbot grid-all"
style="
width:40%;
">
<col style="width:25%;">
<col style="width:75%;">
<tbody>
<tr>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">arm</span></p></td>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">arm-linux-androideabi</span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">arm64</span></p></td>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">aarch64-linux-android</span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">x86</span></p></td>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">i686-linux-android</span></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">x86_64</span></p></td>
<td class="tableblock halign-left valign-top" ><p class="tableblock"><span class="monospaced">x86_64-linux-android</span></p></td>
</tr>
</tbody>
</table>
<div class="paragraph"><p>The port is incomplete, but targets known to be working include <span class="monospaced">crashpad_util</span>,
<span class="monospaced">crashpad_test</span>, and <span class="monospaced">crashpad_test_test</span>. This list will grow over time. To
build, direct <span class="monospaced">ninja</span> to the specific <span class="monospaced">out</span> directory chosen by
<span class="monospaced">--generator-output</span> above.</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>ninja -C out_android_arm64_api21/out/Debug crashpad_test_test</strong></pre>
</div></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_testing">Testing</h2>
<div class="sectionbody">
<div class="paragraph"><p>Crashpad uses <a href="https://github.com/google/googletest/">Google Test</a> as its
unit-testing framework, and some tests use
<a href="https://github.com/google/googletest/tree/master/googlemock/">Google Mock</a> 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
<span class="monospaced">out/Debug/crashpad_*_test</span>.</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>out/Debug/crashpad_minidump_test</strong>
$ <strong>out/Debug/crashpad_util_test</strong></pre>
</div></div>
<div class="paragraph"><p>A script is provided to run all of Crashpads tests. It accepts a single
argument that tells it which configuration to test.</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>python build/run_tests.py Debug</strong></pre>
</div></div>
<div class="sect2">
<h3 id="_android_2">Android</h3>
<div class="paragraph"><p>To test on Android, use
<a href="https://developer.android.com/studio/command-line/adb.html">ADB (Android Debug
Bridge)</a> to <span class="monospaced">adb push</span> test executables and test data to a device or emulator,
then use <span class="monospaced">adb shell</span> to get a shell to run the test executables from. ADB is
part of the <a href="https://developer.android.com/sdk/">Android SDK</a>. Note that it is
sufficient to install just the command-line tools. The entire Android Studio IDE
is not necessary to obtain ADB.</p></div>
<div class="paragraph"><p>This example runs <span class="monospaced">crashpad_test_test</span> 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.</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>adb push out_android_arm64_api21/out/Debug/crashpad_test_test /data/local/tmp/</strong>
[100%] /data/local/tmp/crashpad_test_test
$ <strong>adb push \
out_android_arm64_api21/out/Debug/crashpad_test_test_multiprocess_exec_test_child \
/data/local/tmp/</strong>
[100%] /data/local/tmp/crashpad_test_test_multiprocess_exec_test_child
$ <strong>adb shell mkdir -p /data/local/tmp/crashpad_test_data_root/test</strong>
$ <strong>adb push test/paths_test_data_root.txt \
/data/local/tmp/crashpad_test_data_root/test/</strong>
[100%] /data/local/tmp/crashpad_test_data_root/test/paths_test_data_root.txt
$ <strong>adb shell</strong>
device:/ $ <strong>cd /data/local/tmp</strong>
device:/data/local/tmp $ <strong>CRASHPAD_TEST_DATA_ROOT=crashpad_test_data_root \
./crashpad_test_test</strong></pre>
</div></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_contributing">Contributing</h2>
<div class="sectionbody">
<div class="paragraph"><p>Crashpads contribution process is very similar to
<a href="https://dev.chromium.org/developers/contributing-code">Chromiums contribution
process</a>.</p></div>
<div class="sect2">
<h3 id="_code_review">Code Review</h3>
<div class="paragraph"><p>A code review must be conducted for every change to Crashpads source code. Code
review is conducted on <a href="https://chromium-review.googlesource.com/">Chromiums
Gerrit</a> system, and all code reviews must be sent to an appropriate reviewer,
with a Cc sent to
<a href="https://groups.google.com/a/chromium.org/group/crashpad-dev">crashpad-dev</a>. The
<span class="monospaced">codereview.settings</span> file specifies this environment to <span class="monospaced">git-cl</span>.</p></div>
<div class="paragraph"><p><span class="monospaced">git-cl</span> is part of the
<a href="https://dev.chromium.org/developers/how-tos/depottools">depot_tools</a>. Theres no
need to install it separately.</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>git checkout -b work_branch origin/master</strong>
<em>…do some work…</em>
$ <strong>git add …</strong>
$ <strong>git commit</strong>
$ <strong>git cl upload</strong></pre>
</div></div>
<div class="paragraph"><p>The <a href="https://polygerrit.appspot.com/">PolyGerrit interface</a> 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 pages footer.</p></div>
<div class="paragraph"><p>Uploading a patch to Gerrit does not automatically request a review. You must
select a reviewer on the Gerrit review page after running <span class="monospaced">git cl upload</span>. This
action notifies your reviewer of the code review request. If you have lost track
of the review page, <span class="monospaced">git cl issue</span> will remind you of its URL. Alternatively,
you can request review when uploading to Gerrit by using <span class="monospaced">git cl upload
--send-mail</span>.</p></div>
<div class="paragraph"><p>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 <span class="monospaced">git commit</span>. You can then upload a new
patch set with <span class="monospaced">git cl upload</span> and let your reviewer know youve addressed the
feedback.</p></div>
</div>
<div class="sect2">
<h3 id="_landing_changes">Landing Changes</h3>
<div class="paragraph"><p>After code review is complete and “Code-Review: +1”) has been received from all
reviewers, project members can commit the patch themselves:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ <strong>cd ~/crashpad/crashpad</strong>
$ <strong>git checkout work_branch</strong>
$ <strong>git cl land</strong></pre>
</div></div>
<div class="paragraph"><p>Alternatively, patches can be committed by clicking the “Submit” button in the
Gerrit UI.</p></div>
<div class="paragraph"><p>Crashpad does not currently have a
<a href="https://dev.chromium.org/developers/testing/commit-queue">commit queue</a>, 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.</p></div>
</div>
<div class="sect2">
<h3 id="_external_contributions">External Contributions</h3>
<div class="paragraph"><p>Copyright holders must complete the
<a href="https://developers.google.com/open-source/cla/individual">Individual Contributor
License Agreement</a> or
<a href="https://developers.google.com/open-source/cla/corporate">Corporate Contributor
License Agreement</a> as appropriate before any submission can be accepted, and
must be listed in the <span class="monospaced">AUTHORS</span> file. Contributors may be listed in the
<span class="monospaced">CONTRIBUTORS</span> file.</p></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_buildbot">Buildbot</h2>
<div class="sectionbody">
<div class="paragraph"><p>The <a href="https://build.chromium.org/p/client.crashpad/">Crashpad Buildbot</a> 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.”</p></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
Last updated November 1, 2016
</div>
</div>
</body>
</html>