
BUG=None R=laforge@chromium.org,binji@chromium.org,sbc@chromium.org,rockot@chromium.org Review-Url: https://codereview.chromium.org/2875303003 Cr-Commit-Position: refs/heads/master@{#475662}
606 lines
37 KiB
HTML
606 lines
37 KiB
HTML
{{+bindTo:partials.standard_nacl_article}}
|
|
|
|
<b><font color="#cc0000">
|
|
NOTE:
|
|
Deprecation of the technologies described here has been announced
|
|
for platforms other than ChromeOS.<br/>
|
|
Please visit our
|
|
<a href="/native-client/migration">migration guide</a>
|
|
for details.
|
|
</font></b>
|
|
<hr/><section id="building">
|
|
<h1 id="building">Building</h1>
|
|
<div class="contents local" id="table-of-contents" style="display: none">
|
|
<p class="topic-title first">Table Of Contents</p>
|
|
<ul class="small-gap">
|
|
<li><p class="first"><a class="reference internal" href="#introduction" id="id4">Introduction</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#target-architectures" id="id5">Target architectures</a></li>
|
|
<li><a class="reference internal" href="#c-libraries" id="id6">C libraries</a></li>
|
|
<li><a class="reference internal" href="#c-standard-libraries" id="id7">C++ standard libraries</a></li>
|
|
<li><a class="reference internal" href="#sdk-toolchains" id="id8">SDK toolchains</a></li>
|
|
<li><a class="reference internal" href="#sdk-toolchains-versus-your-hosted-toolchain" id="id9">SDK toolchains versus your hosted toolchain</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference internal" href="#the-pnacl-toolchain" id="id10">The PNaCl toolchain</a></li>
|
|
<li><p class="first"><a class="reference internal" href="#using-the-pnacl-tools-to-compile-link-debug-and-deploy" id="id11">Using the PNaCl tools to compile, link, debug, and deploy</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#compile" id="id12">Compile</a></li>
|
|
<li><a class="reference internal" href="#create-a-static-library" id="id13">Create a static library</a></li>
|
|
<li><a class="reference internal" href="#link-the-application" id="id14">Link the application</a></li>
|
|
<li><a class="reference internal" href="#finalizing-the-pexe-for-deployment" id="id15">Finalizing the <strong>pexe</strong> for deployment</a></li>
|
|
<li><a class="reference internal" href="#compressing-the-pexe-for-deployment" id="id16">Compressing the <strong>pexe</strong> for deployment</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference internal" href="#object-dumping-of-pnacl-bitcode-files" id="id17">Object dumping of PNaCl bitcode files</a></li>
|
|
<li><p class="first"><a class="reference internal" href="#the-gnu-based-toolchains" id="id18">The GNU-based toolchains</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#compiling" id="id19">Compiling</a></li>
|
|
<li><a class="reference internal" href="#creating-libraries-and-linking" id="id20">Creating libraries and Linking</a></li>
|
|
<li><a class="reference internal" href="#finalizing-a-nexe-for-deployment" id="id21">Finalizing a <strong>nexe</strong> for deployment</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference internal" href="#using-make" id="id22">Using make</a></li>
|
|
<li><a class="reference internal" href="#libraries-and-header-files-provided-with-the-sdk" id="id23">Libraries and header files provided with the SDK</a></li>
|
|
<li><p class="first"><a class="reference internal" href="#troubleshooting" id="id24">Troubleshooting</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#undefined-reference-error" id="id25">“Undefined reference” error</a></li>
|
|
<li><a class="reference internal" href="#can-t-find-libraries-containing-necessary-symbols" id="id26">Can’t find libraries containing necessary symbols</a></li>
|
|
<li><a class="reference internal" href="#pnacl-abi-verification-errors" id="id27">PNaCl ABI Verification errors</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
</div><h2 id="introduction">Introduction</h2>
|
|
<p>This document describes how to build Native Client modules. It is intended for
|
|
developers who have experience writing, compiling, and linking C and C++ code.
|
|
If you haven’t read the Native Client <a class="reference internal" href="/native-client/overview.html"><em>Technical Overview</em></a> and <a class="reference internal" href="/native-client/devguide/tutorial/index.html"><em>Tutorial</em></a>, we recommend starting
|
|
with those.</p>
|
|
<h3 id="target-architectures"><span id="id1"></span>Target architectures</h3>
|
|
<p>Portable Native Client (PNaCl) modules are written in C or C++ and compiled
|
|
into an executable file ending in a <strong>.pexe</strong> extension using the PNaCl
|
|
toolchain in the Native Client SDK. Chrome can load <strong>pexe</strong> files
|
|
embedded in web pages and execute them as part of a web application.</p>
|
|
<p>As explained in the Technical Overview, PNaCl modules are
|
|
operating-system-independent <strong>and</strong> processor-independent. The same <strong>pexe</strong>
|
|
will run on Windows, Mac OS X, Linux, and ChromeOS and it will run on x86-32,
|
|
x86-64, ARM and MIPS processors.</p>
|
|
<p>Native Client also supports architecture-specific <strong>nexe</strong> files.
|
|
These <strong>nexe</strong> files are <strong>also</strong> operating-system-independent,
|
|
but they are <strong>not</strong> processor-independent. To support a wide variety of
|
|
devices you must compile separate versions of your Native Client module
|
|
for different processors on end-user machines. A
|
|
<a class="reference internal" href="/native-client/overview.html#application-files"><em>manifest file</em></a> will then specify which version
|
|
of the module to load based on the end-user’s architecture. The SDK
|
|
includes a script for generating manifest files called <code>create_nmf.py</code>. This
|
|
script is located in the <code>pepper_<version>/tools/</code> directory, meaning under
|
|
your installed pepper bundle. For examples of how to compile modules for
|
|
multiple target architectures and how to generate manifest files, see the
|
|
Makefiles included with the SDK examples.</p>
|
|
<p>This section will mostly cover PNaCl, but also describes how to build
|
|
<strong>nexe</strong> applications.</p>
|
|
<h3 id="c-libraries">C libraries</h3>
|
|
<p>The PNaCl toolchain uses the <a class="reference external" href="http://sourceware.org/newlib/">newlib</a> C library and can be used to build
|
|
portable <strong>pexe</strong> files (using <code>pnacl-clang</code>) or <strong>nexe</strong> files (using, for
|
|
example, <code>x86_64-nacl-clang</code>). The Native Client SDK also has a
|
|
GCC-based toolchain for building <strong>nexe</strong> files which uses the <a class="reference external" href="http://www.gnu.org/software/libc/">glibc</a> C library.
|
|
See <a class="reference internal" href="/native-client/devguide/devcycle/dynamic-loading.html"><em>Dynamic Linking & Loading with glibc</em></a> for
|
|
information about these libraries, including factors to help you decide which to
|
|
use.</p>
|
|
<h3 id="c-standard-libraries"><span id="building-cpp-libraries"></span>C++ standard libraries</h3>
|
|
<p>The PNaCl SDK can use either LLVM’s <a class="reference external" href="http://libcxx.llvm.org/">libc++</a>
|
|
(the current default) or GCC’s <a class="reference external" href="http://gcc.gnu.org/libstdc++">libstdc++</a> (deprecated). The
|
|
<code>-stdlib=[libc++|libstdc++]</code> command line argument can be used to
|
|
choose which standard library to use.</p>
|
|
<p>The GCC-based toolchain only has support for GCC’s <a class="reference external" href="http://gcc.gnu.org/libstdc++">libstdc++</a>.</p>
|
|
<p>C++11 library support is only complete in libc++ but other non-library language
|
|
features should work regardless of which standard library is used. The
|
|
<code>-std=gnu++11</code> command line argument can be used to indicate which C++
|
|
language standard to use (<code>-std=c++11</code> often doesn’t work well because newlib
|
|
relies on some GNU extensions).</p>
|
|
<h3 id="sdk-toolchains">SDK toolchains</h3>
|
|
<p>The Native Client SDK includes multiple toolchains. It has one PNaCl toolchain
|
|
and it has multiple GCC-based toolchains that are differentiated by target
|
|
architectures and C libraries. The single PNaCl toolchain is located
|
|
in a directory named <code>pepper_<version>/toolchain/<OS_platform>_pnacl</code>,
|
|
and the GCC-based toolchains are located in directories named
|
|
<code>pepper_<version>/toolchain/<OS_platform>_<architecture>_<c_library></code>.</p>
|
|
<p>The compilers, linkers, and other tools are located in the <code>bin/</code>
|
|
subdirectory in each toolchain. For example, the tools in the Windows SDK
|
|
for PNaCl has a C++ compiler in <code>toolchain/win_pnacl/bin/pnacl-clang++</code>.</p>
|
|
<h3 id="sdk-toolchains-versus-your-hosted-toolchain">SDK toolchains versus your hosted toolchain</h3>
|
|
<p>To build NaCl modules, you must use one of the Native Client toolchains
|
|
included in the SDK. The SDK toolchains use a variety of techniques to
|
|
ensure that your NaCl modules comply with the security constraints of
|
|
the Native Client sandbox.</p>
|
|
<p>During development, you have another choice: You can build modules using a
|
|
<em>standard</em> toolchain, such as the hosted toolchain on your development
|
|
machine. This can be Visual Studio’s standard compiler, XCode, LLVM, or
|
|
GNU-based compilers on your development machine. These standard toolchains
|
|
will not produce executables that comply with the Native Client sandbox
|
|
security constraints. They are also not portable across operating systems
|
|
and not portable across different processors. However, using a standard
|
|
toolchain allows you to develop modules in your favorite IDE and use
|
|
your favorite debugging and profiling tools. The drawback is that modules
|
|
compiled in this manner can only run as Pepper (PPAPI) plugins in Chrome.
|
|
To publish and distribute Native Client modules as part of a web
|
|
application, you must eventually use a toolchain in the Native
|
|
Client SDK.</p>
|
|
<aside class="note">
|
|
In the future, additional tools will be available to compile Native Client
|
|
modules written in other programming languages, such as C#. But this
|
|
document covers only compiling C and C++ code, using the toolchains
|
|
provided in the SDK.
|
|
</aside>
|
|
<h2 id="the-pnacl-toolchain">The PNaCl toolchain</h2>
|
|
<p>The PNaCl toolchain contains modified versions of the tools in the
|
|
LLVM toolchain, as well as linkers and other tools from binutils.
|
|
To determine which version of LLVM or binutils the tools are based upon,
|
|
run the tool with the <code>--version</code> command line flag. These tools
|
|
are used to compile and link applications into <strong>.pexe</strong> files. The toolchain
|
|
also contains a tool to translate a <strong>pexe</strong> file into a
|
|
architecture-specific <strong>.nexe</strong> (e.g., for debugging purposes).</p>
|
|
<p>Some of the useful tools include:</p>
|
|
<dl class="docutils">
|
|
<dt><code>pnacl-abicheck</code></dt>
|
|
<dd>Checks that the <strong>pexe</strong> follows the PNaCl ABI rules.</dd>
|
|
<dt><code>pnacl-ar</code></dt>
|
|
<dd>Creates archives (i.e., static libraries)</dd>
|
|
<dt><code>pnacl-bcdis</code></dt>
|
|
<dd>Object dumper for PNaCl bitcode files.</dd>
|
|
<dt><code>pnacl-clang</code></dt>
|
|
<dd>C compiler and compiler driver</dd>
|
|
<dt><code>pnacl-clang++</code></dt>
|
|
<dd>C++ compiler and compiler driver</dd>
|
|
<dt><code>pnacl-compress</code></dt>
|
|
<dd>Compresses a finalized <strong>pexe</strong> file for deployment.</dd>
|
|
<dt><code>pnacl-dis</code></dt>
|
|
<dd>Disassembler for both <strong>pexe</strong> files and <strong>nexe</strong> files</dd>
|
|
<dt><code>pnacl-finalize</code></dt>
|
|
<dd>Finalizes <strong>pexe</strong> files for deployment</dd>
|
|
<dt><code>pnacl-ld</code></dt>
|
|
<dd>Bitcode linker</dd>
|
|
<dt><code>pnacl-nm</code></dt>
|
|
<dd>Lists symbols in bitcode files, native code, and libraries</dd>
|
|
<dt><code>pnacl-ranlib</code></dt>
|
|
<dd>Generates a symbol table for archives (i.e., static libraries)</dd>
|
|
<dt><code>pnacl-translate</code></dt>
|
|
<dd>Translates a <strong>pexe</strong> to a native architecture, outside of the browser</dd>
|
|
</dl>
|
|
<p>For the full list of tools, see the
|
|
<code>pepper_<version>/toolchain/<platform>_pnacl/bin</code> directory.</p>
|
|
<h2 id="using-the-pnacl-tools-to-compile-link-debug-and-deploy">Using the PNaCl tools to compile, link, debug, and deploy</h2>
|
|
<p>To build an application with the PNaCl SDK toolchain, you must compile
|
|
your code, link it, test and debug it, and then deploy it. This section goes
|
|
over some examples of how to use the tools.</p>
|
|
<h3 id="compile">Compile</h3>
|
|
<p>To compile a simple application consisting of <code>file1.cc</code> and <code>file2.cc</code> into
|
|
<code>hello_world.pexe</code> use the <code>pnacl-clang++</code> tool</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-clang++ \
|
|
file1.cc file2.cc -Inacl_sdk/pepper_<version>/include \
|
|
-Lnacl_sdk/pepper_<version>/lib/pnacl/Release -o hello_world.pexe \
|
|
-g -O2 -lppapi_cpp -lppapi
|
|
</pre>
|
|
<p>The typical application consists of many files. In that case,
|
|
each file can be compiled separately so that only files that are
|
|
affected by a change need to be recompiled. To compile an individual
|
|
file from your application, you must use either the <code>pnacl-clang</code> C
|
|
compiler, or the <code>pnacl-clang++</code> C++ compiler. The compiler produces
|
|
separate bitcode files. For example:</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-clang++ \
|
|
hello_world.cc -Inacl_sdk/pepper_<version>/include -c \
|
|
-o hello_world.o -g -O0
|
|
</pre>
|
|
<p>For a description of each command line flag, run <code>pnacl-clang --help</code>.
|
|
For convenience, here is a description of some of the flags used in
|
|
the example.</p>
|
|
<dl class="docutils" id="compile-flags">
|
|
<dt><code>-c</code></dt>
|
|
<dd>indicates that <code>pnacl-clang++</code> should only compile an individual file,
|
|
rather than continue the build process and link together the
|
|
full application.</dd>
|
|
<dt><code>-o <output_file></code></dt>
|
|
<dd>indicates the <strong>output</strong> filename.</dd>
|
|
<dt><code>-g</code></dt>
|
|
<dd>tells the compiler to include debug information in the result.
|
|
This debug information can be used during development, and then <strong>stripped</strong>
|
|
before actually deploying the application to keep the application’s
|
|
download size small.</dd>
|
|
<dt><code>-On</code></dt>
|
|
<dd><p class="first">sets the optimization level to n. Use <code>-O0</code> when debugging, and <code>-O2</code> or
|
|
<code>-O3</code> for deployment.</p>
|
|
<p class="last">The main difference between <code>-O2</code> and <code>-O3</code> is whether the compiler
|
|
performs optimizations that involve a space-speed tradeoff. It could be the
|
|
case that <code>-O3</code> optimizations are not desirable due to increased <strong>pexe</strong>
|
|
download size; you should make your own performance measurements to determine
|
|
which level of optimization is right for you. When looking at code size, note
|
|
that what you generally care about is not the size of the <strong>pexe</strong> produced by
|
|
<code>pnacl-clang</code>, but the size of the compressed <strong>pexe</strong> that you upload to
|
|
the server or to the Chrome Web Store. Optimizations that increase the size of
|
|
an uncompressed <strong>pexe</strong> may not increase the size of the compressed <strong>pexe</strong>
|
|
very much. You should also verify how optimization level affects on-device
|
|
translation time, this can be tested locally with <code>pnacl-translate</code>.</p>
|
|
</dd>
|
|
<dt><code>-I<directory></code></dt>
|
|
<dd>adds a directory to the search path for <strong>include</strong> files. The SDK has
|
|
Pepper (PPAPI) headers located at <code>nacl_sdk/pepper_<version>/
|
|
include</code>, so add that directory when compiling to be able to include the
|
|
headers.</dd>
|
|
<dt><code>-mllvm -inline-threshold=n</code></dt>
|
|
<dd>change how much inlining is performed by LLVM (the default is 225, a smaller
|
|
value will result in less inlining being performed). The right number to
|
|
choose is application-specific, you’ll therefore want to experiment with the
|
|
value that you pass in: you’ll be trading off potential performance with
|
|
<strong>pexe</strong> size and on-device translation speed.</dd>
|
|
</dl>
|
|
<h3 id="create-a-static-library">Create a static library</h3>
|
|
<p>The <code>pnacl-ar</code> and <code>pnacl-ranlib</code> tools allow you to create a
|
|
<strong>static</strong> library from a set of bitcode files, which can later be linked
|
|
into the full application.</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-ar cr \
|
|
libfoo.a foo1.o foo2.o foo3.o
|
|
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-ranlib libfoo.a
|
|
</pre>
|
|
<h3 id="link-the-application">Link the application</h3>
|
|
<p>The <code>pnacl-clang++</code> tool is used to compile applications, but it can
|
|
also be used link together compiled bitcode and libraries into a
|
|
full application.</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-clang++ \
|
|
-o hello_world.pexe hello_world.o -Lnacl_sdk/pepper_<version>/lib/pnacl/Debug \
|
|
-lfoo -lppapi_cpp -lppapi
|
|
</pre>
|
|
<p>This links the hello world bitcode with the <code>foo</code> library in the example
|
|
as well as the <em>Debug</em> version of the Pepper libraries which are located
|
|
in <code>nacl_sdk/pepper_<version>/lib/pnacl/Debug</code>. If you wish to link
|
|
against the <em>Release</em> version of the Pepper libraries, change the
|
|
<code>-Lnacl_sdk/pepper_<version>/lib/pnacl/Debug</code> to
|
|
<code>-Lnacl_sdk/pepper_<version>/lib/pnacl/Release</code>.</p>
|
|
<p>In a release build you’ll want to pass <code>-O2</code> to the compiler <em>as well as to
|
|
the linker</em> to enable link-time optimizations. This reduces the size and
|
|
increases the performance of the final <strong>pexe</strong>, and leads to faster downloads
|
|
and on-device translation.</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-clang++ \
|
|
-o hello_world.pexe hello_world.o -Lnacl_sdk/pepper_<version>/lib/pnacl/Release \
|
|
-lfoo -lppapi_cpp -lppapi -O2
|
|
</pre>
|
|
<p>By default the link step will turn all C++ exceptions into calls to <code>abort()</code>
|
|
to reduce the size of the final <strong>pexe</strong> as well as making it translate and run
|
|
faster. If you want to use C++ exceptions you should use the
|
|
<code>--pnacl-exceptions=sjlj</code> linker flag as explained in the <a class="reference internal" href="/native-client/reference/pnacl-c-cpp-language-support.html#exception-handling"><em>exception
|
|
handling</em></a> section of the C++ language support reference.</p>
|
|
<h3 id="finalizing-the-pexe-for-deployment">Finalizing the <strong>pexe</strong> for deployment</h3>
|
|
<p>Typically you would run the application to test it and debug it if needed before
|
|
deploying. See the <a class="reference internal" href="/native-client/devguide/devcycle/running.html"><em>running</em></a> documentation for how to run a PNaCl
|
|
application, and see the <a class="reference internal" href="/native-client/devguide/devcycle/debugging.html"><em>debugging</em></a> documentation for
|
|
debugging techniques and workflow. After testing a PNaCl application, you must
|
|
<strong>finalize</strong> it. The <code>pnacl-finalize</code> tool handles this.</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-finalize \
|
|
hello_world.pexe -o hello_world.final.pexe
|
|
</pre>
|
|
<p>Prior to finalization, the application <strong>pexe</strong> is stored in a binary
|
|
format that is subject to change. After finalization, the application
|
|
<strong>pexe</strong> is <strong>rewritten</strong> into a different binary format that is <strong>stable</strong>
|
|
and will be supported by future versions of PNaCl. The finalization step
|
|
also helps minimize the size of your application for distribution by
|
|
stripping out debug information and other metadata.</p>
|
|
<p>Once the application is finalized, be sure to adjust the manifest file to
|
|
refer to the final version of the application before deployment.
|
|
The <code>create_nmf.py</code> tool helps generate an <code>.nmf</code> file, but <code>.nmf</code>
|
|
files can also be written by hand.</p>
|
|
<h3 id="compressing-the-pexe-for-deployment"><span id="pnacl-compress"></span>Compressing the <strong>pexe</strong> for deployment</h3>
|
|
<p>Size compression is an optional step for deployment, and reduces the size of the
|
|
<strong>pexe</strong> file that must be transmitted over the wire, resulting in faster
|
|
download speed. The tool <code>pnacl-compress</code> applies compression strategies that
|
|
are already built into the <strong>stable</strong> binary format of a <strong>pexe</strong>
|
|
application. As such, compressed <strong>pexe</strong> files do not need any extra time to be
|
|
decompressed on the client’s side. All costs are upfront when you call
|
|
<code>pnacl-compress</code>.</p>
|
|
<p>Currently, this tool will compress <strong>pexe</strong> files by about 25%. However,
|
|
it is somewhat slow (can take from seconds to minutes on large
|
|
appications). Hence, this step is optional.</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-compress \
|
|
hello_world.final.pexe
|
|
</pre>
|
|
<p><code>pnacl-compress</code> must be called after a <strong>pexe</strong> file has been finalized for
|
|
deployment (via <code>pnacl-finalize</code>). Alternatively, you can apply this step as
|
|
part of the finalizing step by adding the <code>--compress</code> flag to the
|
|
<code>pnacl-finalize</code> command line.</p>
|
|
<p>This compression step doesn’t replace the gzip compression performed web servers
|
|
configured for HTTP compression: both compressions are complementary. You’ll
|
|
want to configure your web server to gzip <strong>pexe</strong> files: the gzipped version of
|
|
a compressed <strong>pexe</strong> file is smaller than the corresponding uncompressed
|
|
<strong>pexe</strong> file by 7.5% to 10%.</p>
|
|
<h2 id="object-dumping-of-pnacl-bitcode-files"><span id="pnacl-bcdis"></span>Object dumping of PNaCl bitcode files</h2>
|
|
<p>Sometimes you may be interesting in the contents of a PNaCl bitcode file. The
|
|
tool <code>pnacl-bcdis</code> object dumps the contents of a PNaCl bitcode file. For a
|
|
description of the output produced by this tool, see
|
|
<a class="reference internal" href="/native-client/reference/pnacl-bitcode-manual.html"><em>Contents Of PNaCl Bitcode Files</em></a>.</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_pnacl/bin/pnacl-bcdis \
|
|
hello_world.final.pexe
|
|
</pre>
|
|
<p>The output is the corresponding contents of the given <strong>pexe</strong>.</p>
|
|
<h2 id="the-gnu-based-toolchains">The GNU-based toolchains</h2>
|
|
<p>Besides the PNaCl toolchain, the Native Client SDK also includes modified
|
|
versions of the tools in the standard GNU toolchain, including the GCC
|
|
compilers and the linkers and other tools from binutils. These tools only
|
|
support building <strong>nexe</strong> files. Run the tool with the <code>--version</code>
|
|
command line flag to determine the current version of the tools.</p>
|
|
<p>Each tool in the toolchain is prefixed with the name of the target
|
|
architecture. In the toolchain for the ARM target architecture, each
|
|
tool’s name is preceded by the prefix “arm-nacl-”. In the toolchains for
|
|
the x86 target architecture, there are actually two versions of each
|
|
tool—one to build Native Client modules for the x86-32
|
|
target architecture, and one to build modules for the x86-64 target
|
|
architecture. “i686-nacl-” is the prefix for tools used to build
|
|
32-bit <strong>.nexes</strong>, and “x86_64-nacl-” is the prefix for tools used to
|
|
build 64-bit <strong>.nexes</strong>.</p>
|
|
<p>These prefixes conform to gcc naming standards and make it easy to use tools
|
|
like autoconf. As an example, you can use <code>i686-nacl-gcc</code> to compile 32-bit
|
|
<strong>.nexes</strong>, and <code>x86_64-nacl-gcc</code> to compile 64-bit <strong>.nexes</strong>. Note that you
|
|
can typically override a tool’s default target architecture with command line
|
|
flags, e.g., you can specify <code>x86_64-nacl-gcc -m32</code> to compile a 32-bit
|
|
<strong>.nexe</strong>.</p>
|
|
<p>The GNU-based SDK toolchains include the following tools:</p>
|
|
<ul class="small-gap">
|
|
<li><prefix>addr2line</li>
|
|
<li><prefix>ar</li>
|
|
<li><prefix>as</li>
|
|
<li><prefix>c++</li>
|
|
<li><prefix>c++filt</li>
|
|
<li><prefix>cpp</li>
|
|
<li><prefix>g++</li>
|
|
<li><prefix>gcc</li>
|
|
<li><prefix>gcc-4.4.3</li>
|
|
<li><prefix>gccbug</li>
|
|
<li><prefix>gcov</li>
|
|
<li><prefix>gprof</li>
|
|
<li><prefix>ld</li>
|
|
<li><prefix>nm</li>
|
|
<li><prefix>objcopy</li>
|
|
<li><prefix>objdump</li>
|
|
<li><prefix>ranlib</li>
|
|
<li><prefix>readelf</li>
|
|
<li><prefix>size</li>
|
|
<li><prefix>strings</li>
|
|
<li><prefix>strip</li>
|
|
</ul>
|
|
<h3 id="compiling">Compiling</h3>
|
|
<p>Compiling files with the GNU-based toolchain is similar to compiling
|
|
files with the PNaCl-based toolchain, except that the output is
|
|
architecture specific.</p>
|
|
<p>For example, assuming you’re developing on a Windows machine, targeting the x86
|
|
architecture you can compile a 32-bit <strong>.nexe</strong> for the hello_world example with
|
|
the following command:</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/win_x86_glibc/bin/i686-nacl-gcc \
|
|
hello_world.c -Inacl_sdk/pepper_<version>/include \
|
|
-Lnacl_sdk/pepper_<version>/lib/glibc/Release -o hello_world_x86_32.nexe \
|
|
-m32 -g -O2 -lppapi
|
|
</pre>
|
|
<p>To compile a 64-bit <strong>.nexe</strong>, you can run the same command but use -m64 instead
|
|
of -m32. Alternatively, you could also use the version of the compiler that
|
|
targets the x86-64 architecture, i.e., <code>x86_64-nacl-gcc</code>.</p>
|
|
<p>You should name executable modules with a <strong>.nexe</strong> filename extension,
|
|
regardless of what platform you’re using.</p>
|
|
<h3 id="creating-libraries-and-linking">Creating libraries and Linking</h3>
|
|
<p>Creating libraries and linking with the GNU-based toolchain is similar
|
|
to doing the same with the PNaCl toolchain. The relevant tools
|
|
for creating <strong>static</strong> libraries are <code><prefix>ar</code> and <code><prefix>ranlib</code>.
|
|
Linking can be done with <code><prefix>g++</code>. See the
|
|
<a class="reference internal" href="/native-client/devguide/devcycle/dynamic-loading.html"><em>Dynamic Linking & Loading with glibc</em></a>
|
|
section on how to create <strong>shared</strong> libraries.</p>
|
|
<h3 id="finalizing-a-nexe-for-deployment">Finalizing a <strong>nexe</strong> for deployment</h3>
|
|
<p>Unlike the PNaCl toolchain, no separate finalization step is required
|
|
for <strong>nexe</strong> files. The <strong>nexe</strong> files are always in a <strong>stable</strong> format.
|
|
However, the <strong>nexe</strong> file may contain debug information and symbol information
|
|
which may make the <strong>nexe</strong> file larger than needed for distribution.
|
|
To minimize the size of the distributed file, you can run the
|
|
<code><prefix>strip</code> tool to strip out debug information.</p>
|
|
<h2 id="using-make">Using make</h2>
|
|
<p>This document doesn’t cover how to use <code>make</code>, but if you want to use
|
|
<code>make</code> to build your Native Client module, you can base your Makefile on the
|
|
ones in the SDK examples.</p>
|
|
<p>The Makefiles for the SDK examples build most of the examples in multiple
|
|
configurations (using PNaCl vs NaCl, using different C libraries,
|
|
targeting different architectures, and using different levels of optimization).
|
|
To select a specific toolchain, set the <strong>environment variable</strong>
|
|
<code>TOOLCHAIN</code> to either <code>pnacl</code>, <code>clang-newlib</code>, <code>glibc</code>, or <code>host</code>.
|
|
To select a specific level of optimization set the <strong>environment
|
|
variable</strong> <code>CONFIG</code> to either <code>Debug</code>, or <code>Release</code>. Running
|
|
<code>make</code> in each example’s directory does <strong>one</strong> of the following,
|
|
depending on the setting of the environment variables.</p>
|
|
<ul class="small-gap">
|
|
<li><p class="first">If <code>TOOLCHAIN=pnacl</code> creates a subdirectory called <code>pnacl</code>;</p>
|
|
<ul class="small-gap">
|
|
<li>builds a <strong>.pexe</strong> (architecture-independent Native Client executable) using
|
|
the newlib library</li>
|
|
<li>generates a Native Client manifest (.nmf) file for the pnacl version of the
|
|
example</li>
|
|
</ul>
|
|
</li>
|
|
<li><p class="first">If <code>TOOLCHAIN=clang-newlib</code> creates a subdirectory called <code>clang-newlib</code>;</p>
|
|
<ul class="small-gap">
|
|
<li>builds <strong>.nexes</strong> for the x86-32, x86-64, and ARM architectures using the
|
|
nacl-clang toolchain and the newlib C library</li>
|
|
<li>generates a Native Client manifest (.nmf) file for the clang-newlib version
|
|
of the example</li>
|
|
</ul>
|
|
</li>
|
|
<li><p class="first">If <code>TOOLCHAIN=glibc</code> creates a subdirectory called <code>glibc</code>;</p>
|
|
<ul class="small-gap">
|
|
<li>builds <strong>.nexes</strong> for the x86-32, x86-64 and ARM architectures using the
|
|
glibc library</li>
|
|
<li>generates a Native Client manifest (.nmf) file for the glibc version of the
|
|
example</li>
|
|
</ul>
|
|
</li>
|
|
<li><p class="first">If <code>TOOLCHAIN=host</code> creates a subdirectory called <code>windows</code>, <code>linux</code>,
|
|
or <code>mac</code> (depending on your development machine);</p>
|
|
<ul class="small-gap">
|
|
<li>builds a Pepper plugin (.dll for Windows, .so for Linux/Mac) using the
|
|
hosted toolchain on your development machine</li>
|
|
<li>generates a Native Client manifest (.nmf) file for the host Pepper plugin
|
|
version of the example</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<aside class="note">
|
|
The glibc library is not yet available for the ARM and PNaCl toolchains.
|
|
</aside>
|
|
<p>Here is how to build the examples with PNaCl in Release mode on Windows.
|
|
The resulting files for <code>examples/api/audio</code> will be in
|
|
<code>examples/api/audio/pnacl/Release</code>, and the directory layout is similar for
|
|
other examples.</p>
|
|
<pre>
|
|
set TOOLCHAIN=pnacl
|
|
set CONFIG=Release
|
|
make
|
|
</pre>
|
|
<p>Your Makefile can be simpler since you will not likely want to build so many
|
|
different configurations of your module. The example Makefiles define
|
|
numerous variables near the top (e.g., <code>CFLAGS</code>) that make it easy
|
|
to customize the commands that are executed for your project and the options
|
|
for each command.</p>
|
|
<p>For details on how to use make, see the <a class="reference external" href="http://www.gnu.org/software/make/manual/make.html">GNU ‘make’ Manual</a>.</p>
|
|
<h2 id="libraries-and-header-files-provided-with-the-sdk">Libraries and header files provided with the SDK</h2>
|
|
<p>The Native Client SDK includes modified versions of standard toolchain-support
|
|
libraries, such as libpthread and libc, plus the relevant header files.
|
|
The standard libraries are located under the <code>/pepper_<version></code> directory
|
|
in the following locations:</p>
|
|
<ul class="small-gap">
|
|
<li>PNaCl toolchain: <code>toolchain/<platform>_pnacl/usr/lib</code></li>
|
|
<li>x86 toolchains: <code>toolchain/<platform>_x86_<c_library>/x86_64-nacl/lib32</code> and
|
|
<code>/lib64</code> (for the 32-bit and 64-bit target architectures, respectively)</li>
|
|
<li>ARM toolchain: <code>toolchain/<platform>_arm_<c_library>/arm-nacl/lib</code></li>
|
|
</ul>
|
|
<p>For example, on Windows, the libraries for the x86-64 architecture in the
|
|
glibc toolchain are in <code>toolchain/win_x86_glibc/x86_64-nacl/lib64</code>.</p>
|
|
<p>The header files are in:</p>
|
|
<ul class="small-gap">
|
|
<li>PNaCl toolchain: <code>toolchain/<platform>_pnacl/le32-nacl/include</code></li>
|
|
<li>clang newlib toolchains: <code>toolchain/<platform>_pnacl/<arch>-nacl/include</code></li>
|
|
<li>x86 glibc toolchain: <code>toolchain/<platform>_x86_glibc/x86_64-nacl/include</code></li>
|
|
<li>ARM glibc toolchain: <code>toolchain/<platform>_arm_glibc/arm-nacl/include</code></li>
|
|
</ul>
|
|
<p>Many other libraries have been ported for use with Native Client; for more
|
|
information, see the <a class="reference external" href="https://chromium.googlesource.com/webports">webports</a>
|
|
project. If you port an open-source library for your own use, we recommend
|
|
adding it to webports.</p>
|
|
<p>Besides the standard libraries, the SDK includes Pepper libraries.
|
|
The PNaCl Pepper libraries are located in the the
|
|
<code>nacl_sdk/pepper_<version>/lib/pnacl/<Release or Debug></code> directory.
|
|
The GNU-based toolchain has Pepper libraries in
|
|
<code>nacl_sdk/pepper_<version>/lib/glibc_<arch>/<Release or Debug></code>
|
|
and <code>nacl_sdk/pepper_<version>/lib/clang-newlib_<arch>/<Release or Debug></code>.
|
|
The libraries provided by the SDK allow the application to use Pepper,
|
|
as well as convenience libraries to simplify porting an application that
|
|
uses POSIX functions. Here are descriptions of the Pepper libraries provided
|
|
in the SDK.</p>
|
|
<dl class="docutils" id="devcycle-building-nacl-io">
|
|
<dt>libppapi.a</dt>
|
|
<dd>Implements the Pepper (PPAPI) C interface. Needed for all applications that
|
|
use Pepper (even C++ applications).</dd>
|
|
<dt>libppapi_cpp.a</dt>
|
|
<dd>Implements the Pepper (PPAPI) C++ interface. Needed by C++ applications that
|
|
use Pepper.</dd>
|
|
<dt>libppapi_gles2.a</dt>
|
|
<dd>Implements the Pepper (PPAPI) GLES interface. Needed by applications
|
|
that use the 3D graphics API.</dd>
|
|
<dt>libnacl_io.a</dt>
|
|
<dd>Provides a POSIX layer for NaCl. In particular, the library provides a
|
|
virtual file system and support for sockets. The virtual file system
|
|
allows a module to “mount” a given directory tree. Once a module has
|
|
mounted a file system, it can use standard C library file operations:
|
|
<code>fopen</code>, <code>fread</code>, <code>fwrite</code>, <code>fseek</code>, and <code>fclose</code>.
|
|
For more detail, see the header <code>include/nacl_io/nacl_io.h</code>.
|
|
For an example of how to use nacl_io, see <code>examples/demo/nacl_io_demo</code>.</dd>
|
|
<dt>libppapi_simple.a</dt>
|
|
<dd>Provides a familiar C programming environment by letting a module have a
|
|
simple <code>main()</code> entry point. The entry point is similar to the standard C
|
|
<code>main()</code> function, complete with <code>argc</code> and <code>argv[]</code> parameters. For
|
|
details see <code>include/ppapi_simple/ps.h</code>. For an example of
|
|
how to use ppapi_simple, <code>see examples/tutorial/using_ppapi_simple</code>.</dd>
|
|
</dl>
|
|
<aside class="note">
|
|
<ul class="small-gap">
|
|
<li>Since the Native Client toolchains use their own library and header search
|
|
paths, the tools won’t find third-party libraries you use in your
|
|
non-Native-Client development. If you want to use a specific third-party
|
|
library for Native Client development, look for it in <a class="reference external" href="https://chromium.googlesource.com/webports">webports</a>, or port the library yourself.</li>
|
|
<li>The order in which you list libraries in your build commands is important,
|
|
since the linker searches and processes libraries in the order in which they
|
|
are specified. See the <code>\*_LDFLAGS</code> variables in the Makefiles of the SDK
|
|
examples for the order in which specific libraries should be listed.</li>
|
|
</ul>
|
|
|
|
</aside>
|
|
<h2 id="troubleshooting">Troubleshooting</h2>
|
|
<p>Some common problems, and how to fix them:</p>
|
|
<h3 id="undefined-reference-error">“Undefined reference” error</h3>
|
|
<p>An “undefined reference” error may indicate incorrect link order and/or
|
|
missing libraries. For example, if you leave out <code>-lppapi</code> when
|
|
compiling Pepper applications you’ll see a series of undefined
|
|
reference errors.</p>
|
|
<p>One common type of “undefined reference” error is with respect to certain
|
|
system calls, e.g., “undefined reference to ‘mkdir’”. For security reasons,
|
|
Native Client does not support a number of system calls. Depending on how
|
|
your code uses such system calls, you have a few options:</p>
|
|
<ol class="arabic simple">
|
|
<li>Link with the <code>-lnosys</code> flag to provide empty/always-fail versions of
|
|
unsupported system calls. This will at least get you past the link stage.</li>
|
|
<li>Find and remove use of the unsupported system calls.</li>
|
|
<li>Create your own implementation of the unsupported system calls to do
|
|
something useful for your application.</li>
|
|
</ol>
|
|
<p>If your code uses mkdir or other file system calls, you might find the
|
|
<a class="reference internal" href="#devcycle-building-nacl-io"><em>nacl_io</em></a> library useful.
|
|
The nacl_io library essentially does option (3) for you: It lets your
|
|
code use POSIX-like file system calls, and implements the calls using
|
|
various technologies (e.g., HTML5 file system, read-only filesystems that
|
|
use URL loaders, or an in-memory filesystem).</p>
|
|
<h3 id="can-t-find-libraries-containing-necessary-symbols">Can’t find libraries containing necessary symbols</h3>
|
|
<p>Here is one way to find the appropriate library for a given symbol:</p>
|
|
<pre>
|
|
nacl_sdk/pepper_<version>/toolchain/<platform>_pnacl/bin/pnacl-nm -o \
|
|
nacl_sdk/pepper_<version>toolchain/<platform>_pnacl/usr/lib/*.a | \
|
|
grep <MySymbolName>
|
|
</pre>
|
|
<h3 id="pnacl-abi-verification-errors">PNaCl ABI Verification errors</h3>
|
|
<p>PNaCl has restrictions on what is supported in bitcode. There is a bitcode
|
|
ABI verifier which checks that the application conforms to the ABI restrictions,
|
|
before it is translated and run in the browser. However, it is best to
|
|
avoid runtime errors for users, so the verifier also runs on the developer’s
|
|
machine at link time.</p>
|
|
<p>For example, the following program which uses 128-bit integers
|
|
would compile with NaCl GCC for the x86-64 target. However, it is not
|
|
portable and would not compile with NaCl GCC for the i686 target.
|
|
With PNaCl, it would fail to pass the ABI verifier:</p>
|
|
<pre class="prettyprint">
|
|
typedef unsigned int uint128_t __attribute__((mode(TI)));
|
|
|
|
uint128_t foo(uint128_t x) {
|
|
return x;
|
|
}
|
|
</pre>
|
|
<p>With PNaCl you would get the following error at link time:</p>
|
|
<pre class="prettyprint">
|
|
Function foo has disallowed type: i128 (i128)
|
|
LLVM ERROR: PNaCl ABI verification failed
|
|
</pre>
|
|
<p>When faced with a PNaCl ABI verification error, check the list of features
|
|
that are <a class="reference internal" href="/native-client/nacl-and-pnacl.html#when-to-use-nacl"><em>not supported by PNaCl</em></a>.
|
|
If the problem you face is not listed as restricted,
|
|
<a class="reference internal" href="/native-client/help.html#help"><em>let us know</em></a>!</p>
|
|
</section>
|
|
|
|
{{/partials.standard_nacl_article}}
|