| Index: native_client_sdk/src/doc/devguide/devcycle/building.rst
|
| diff --git a/native_client_sdk/src/doc/devguide/devcycle/building.rst b/native_client_sdk/src/doc/devguide/devcycle/building.rst
|
| index edfaf6ce21b56767cf48abb4d8a23d5b0820f450..413d6b0d811f6c6d09d6dc68f461d0ac7a0b64ae 100644
|
| --- a/native_client_sdk/src/doc/devguide/devcycle/building.rst
|
| +++ b/native_client_sdk/src/doc/devguide/devcycle/building.rst
|
| @@ -4,4 +4,451 @@
|
| Building
|
| ########
|
|
|
| -foo
|
| +.. contents:: Table Of Contents
|
| + :local:
|
| + :backlinks: none
|
| + :depth: 2
|
| +
|
| +
|
| +Introduction
|
| +============
|
| +
|
| +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 :doc:`Technical Overview
|
| +<../../overview>` and :doc:`Tutorial <../tutorial>`, we recommend starting
|
| +with those.
|
| +
|
| +Target architectures
|
| +--------------------
|
| +
|
| +Native Client modules are written in C or C++ and compiled into executable
|
| +files ending in a .nexe extension using one of the toolchains in the Native
|
| +Client SDK. Chrome can load .nexe files embedded in web pages and execute the
|
| +.nexe files as part of a web application.
|
| +
|
| +As explained in the Technical Overview, Native Client modules are
|
| +operating-system-independent, not processor-independent. Therefore, you must
|
| +compile separate versions of your Native Client module for different processors
|
| +on end-user machines, such as x86-32, x86-64, and ARM. The list below shows
|
| +which .nexe modules run on which target architectures:
|
| +
|
| +**x86 32-bit .nexe modules run on**:
|
| +
|
| +* Windows 32-bit
|
| +* Mac
|
| +* Linux 32-bit
|
| +* Linux 64-bit (but only with 32-bit Chrome)
|
| +
|
| +**x86 64-bit .nexe modules run on**:
|
| +
|
| +* Windows 64-bit
|
| +* Linux 64-bit (but only with 64-bit Chrome).
|
| +
|
| +**ARM .nexe modules run on**:
|
| +
|
| +* ARM devices
|
| +
|
| +In general, you must compile a module for the 32-bit and 64-bit x86 target
|
| +architectures (we also strongly recommend compiling modules for the ARM
|
| +architecture), and create a :ref:`manifest file <application_files>` that
|
| +specifies which version of the module to load based on the end-user's
|
| +architecture. The SDK includes a script, ``create_nmf.py`` (in the ``tools/``
|
| +directory) to generate manifest files. 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.
|
| +
|
| +C libraries
|
| +-----------
|
| +
|
| +The Native Client SDK comes with two C libraries: `newlib
|
| +<http://sourceware.org/newlib/>`_ and `glibc
|
| +<http://www.gnu.org/software/libc/>`_. See :doc:`Dynamic Linking & Loading with
|
| +glibc <dynamic-loading>` for information about these libraries, including
|
| +factors to help you decide which to use.
|
| +
|
| +SDK toolchains
|
| +--------------
|
| +
|
| +The Native Client SDK includes multiple toolchains, differentiated by target
|
| +architectures and C libraries. The toolchains are located in directories named
|
| +``toolchain/<platform>_<architecture>_<library>``, where:
|
| +
|
| +* *<platform>* is the platform of your development machine (win, mac, or linux)
|
| +* *<architecture>* is your target architecture (x86 or arm)
|
| +* *<library>* is the C library you are compiling with (newlib or glibc)
|
| +
|
| +The compilers, linkers, and other tools are located in the bin/ subdirectory in
|
| +each toolchain. For example, the tools in the Windows SDK for the x86 target
|
| +architecture using the newlib library are in ``toolchain/win_x86_newlib/bin``.
|
| +
|
| +.. Note::
|
| + :class: note
|
| +
|
| + The SDK toolchains descend from the ``toolchain/`` directory. The SDK also
|
| + has a ``tools/`` directory; this directory contains utilities that are not
|
| + properly part of the toolchains but that you may find helpful in building and
|
| + testing your application (e.g., the ``create_nmf.py`` script, which you can
|
| + use to create a manifest file).
|
| +
|
| +SDK toolchains versus your hosted toolchain
|
| +-------------------------------------------
|
| +
|
| +To build .nexe files, 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
|
| +``.nexe`` files comply with the security constraints of the Native Client
|
| +sandbox.
|
| +
|
| +During development, you have another choice: You can build modules using a
|
| +standard GNU toolchain, such as the hosted toolchain on your development
|
| +machine. The benefit of using a standard GNU toolchain is that you can 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 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 to create ``.nexe`` files.
|
| +
|
| +.. Note::
|
| + :class: note
|
| +
|
| + * Documentation on how to compile and run modules as Pepper plugins will be
|
| + published soon.
|
| + * 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 modified GNU
|
| + toolchains provided in the SDK.
|
| +
|
| +Tools
|
| +=====
|
| +
|
| +The Native Client toolchains contain modified versions of the tools in the
|
| +standard GNU toolchain, including the gcc compilers (currently version 4.4) and
|
| +the linkers and other tools from binutils (currently version 2.20).
|
| +
|
| +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. Each
|
| +tool's name is preceded by one of the following prefixes:
|
| +
|
| +i686-nacl-
|
| + prefix for tools used to build 32-bit .nexes
|
| +
|
| +x86_64-nacl-
|
| + prefix for tools used to build 64-bit .nexes
|
| +
|
| +These prefixes conform to gcc naming standards and make it easy to use tools
|
| +like autoconf. As an example, you can use ``i686-nacl-gcc`` to compile 32-bit
|
| +.nexes, and ``x86_64-nacl-gcc`` to compile 64-bit .nexes. Note that you can
|
| +typically override a tool's default target architecture with command line
|
| +flags, e.g., you can specify ``x86_64-nacl-gcc -m32`` to compile a 32-bit
|
| +.nexe.
|
| +
|
| +The SDK toolchains include the following tools:
|
| +
|
| +* <prefix>addr2line
|
| +* <prefix>ar
|
| +* <prefix>as
|
| +* <prefix>c++
|
| +* <prefix>c++filt
|
| +* <prefix>cpp
|
| +* <prefix>g++
|
| +* <prefix>gcc
|
| +* <prefix>gcc-4.4.3
|
| +* <prefix>gccbug
|
| +* <prefix>gcov
|
| +* <prefix>gprof
|
| +* <prefix>ld
|
| +* <prefix>nm
|
| +* <prefix>objcopy
|
| +* <prefix>objdump
|
| +* <prefix>ranlib
|
| +* <prefix>readelf
|
| +* <prefix>size
|
| +* <prefix>strings
|
| +* <prefix>strip
|
| +
|
| +Compiling
|
| +=========
|
| +
|
| +To create a .nexe file, use a compiler in one of the Native Client toolchains.
|
| +
|
| +For example, assuming you're developing on a Windows machine, targeting the x86
|
| +architecture, and using the newlib library, you can compile a 32-bit .nexe for
|
| +the hello_world example with the following command::
|
| +
|
| + <NACL_SDK_ROOT>/toolchain/win_x86_newlib/bin/i686-nacl-gcc hello_world.c ^
|
| + -o hello_world_x86_32.nexe -m32 -g -O0 -lppapi
|
| +
|
| +(The carat ``^`` allows the command to span multiple lines on Windows; to do the
|
| +same on Mac and Linux use a back slash instead. Or you can simply type the
|
| +command and all its arguments on one line. ``<NACL_SDK_ROOT>`` represents the
|
| +path to the top-level directory of the bundle you are using, e.g.,
|
| +``<location-where-you-installed-the-SDK>/pepper_28``.)
|
| +
|
| +To compile a 64-bit .nexe, 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., ``x86_64-nacl-gcc``.
|
| +
|
| +You should name executable modules with a ``.nexe`` filename extension,
|
| +regardless of what platform you're using.
|
| +
|
| +Compile flags for different development scenarios
|
| +=================================================
|
| +
|
| +To optimize the performance of your .nexe module, you must use the correct set
|
| +of flags when you compile with nacl-gcc. If you're used to working with an IDE
|
| +rather than with a command-line compiler like gcc, you may not be familiar with
|
| +which flags you need to specify. The table below summarizes which flags to
|
| +specify based on different development scenarios.
|
| +
|
| +===================== =================================================================
|
| +Development scenarios Flags for nacl-gcc
|
| +===================== =================================================================
|
| +debugging -g -O0
|
| +profile [-g] -O{2|3} -msse -mfpmath=sse -ffast-math -fomit-frame-pointer
|
| +deploy -s -O{2|3} -msse -mfpmath=sse -ffast-math -fomit-frame-pointer
|
| +===================== =================================================================
|
| +
|
| +A few of these flags are described below:
|
| +
|
| +-g
|
| + Produce debugging information.
|
| +
|
| +-On
|
| + Optimize the executable for both performance and code size. A higher n
|
| + increases the level of optimization. Use -O0 when debugging, and -O2 or -O3
|
| + for profiling and deployment.
|
| +
|
| + The main difference between -O2 and -O3 is whether the compiler performs
|
| + optimizations that involve a space-speed tradeoff. It could be the case that
|
| + these optimizations are not desirable due to .nexe 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 .nexe produced by nacl-gcc, but
|
| + the size of the compressed .nexe that you upload to the Chrome Web Store.
|
| + Optimizations that increase the size of a .nexe may not increase the size of
|
| + the compressed .nexe that much.
|
| +
|
| + For additional information about optimizations, see the `gcc optimization
|
| + options <http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html>`_. Note
|
| + that the -Os option (optimize for size) is not currently supported.
|
| +
|
| +-s
|
| + Strip the .nexe, i.e., remove all symbol table and relocation information
|
| + from the executable.
|
| +
|
| + As an alternative to using the -s option, you can store a copy of the
|
| + non-stripped .nexe somewhere so that you can extract symbol information from
|
| + it if necessary, and use the nacl-strip tool in the SDK to strip symbol
|
| + information from the .nexe that you deploy.
|
| +
|
| +.. Note::
|
| + :class: note
|
| +
|
| + To see how the examples in the SDK are built, run make in any of the example
|
| + subdirectories (e.g., examples/hello_world). The make tool displays the full
|
| + command lines it runs for each step of the build process (compiling, linking,
|
| + and generating Native Client manifest files).
|
| +
|
| +For additional information about compiler options, see `gcc command options
|
| +<http://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html>`_.
|
| +
|
| +Using make
|
| +==========
|
| +
|
| +This document doesn't cover how to use ``make``, but if you want to use
|
| +``make`` to build your Native Client module, you can base your Makefile on the
|
| +ones in the SDK examples.
|
| +
|
| +The Makefiles for the SDK examples build most of the examples in multiple
|
| +configurations (using different C libraries, targeting different architectures,
|
| +and using different levels of optimization). With a few exceptions (tumbler,
|
| +debugging, and dlopen), running ``make`` in each example's directory does the
|
| +following:
|
| +
|
| +* creates a subdirectory called ``newlib``;
|
| +
|
| + * builds .nexes for the x86-32, x86-64, and ARM architectures using the
|
| + newlib library;
|
| + * generates a Native Client manifest (.nmf) file for the newlib version of
|
| + the example;
|
| +
|
| +* creates a subdirectory called ``glibc``;
|
| +
|
| + * builds .nexes for the x86-32 and x86-64 architectures using the glibc
|
| + library;
|
| + * generates a Native Client manifest (.nmf) file for the glibc version of the
|
| + example;
|
| +
|
| +* creates a subdirectory called ``windows``, ``linux``, or ``mac`` (depending
|
| + on your development machine);
|
| +
|
| + * builds a Pepper plugin (.dll for Windows, .so for Linux/Mac) using the
|
| + hosted toolchain on your development machine;
|
| + * generates a Native Client manifest (.nmf) file for the glibc version of the
|
| + example;
|
| +
|
| +* creates a subdirectory called ``pnacl``;
|
| +
|
| + * builds a .pexe (architecture-independent Native Client executable) using
|
| + the newlib library; and
|
| + * generates a Native Client manifest (.nmf) file for the pnacl version of the
|
| + example;
|
| +
|
| +.. Note::
|
| + :class: note
|
| +
|
| + * The examples are also built using different optimization levels, and the
|
| + executable and manifest files are actually located in subdirectories called
|
| + "Debug" and "Release".
|
| + * The glibc library is not yet available for the ARM and PNaCl toolchains.
|
| + * Chrome does not yet directly support .pexe files, but the PNaCl toolchain
|
| + contains a tool to translate .pexes into .nexes.
|
| +
|
| + 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., ``GLIBC_CCFLAGS``) that make it easy
|
| + to customize the commands that are executed for your project and the options
|
| + for each command.
|
| +
|
| + In addition to building .nexe files, the example Makefiles also generate
|
| + Native Client manifest (.nmf) files, which your application points to from
|
| + the ``src`` attribute of an ``<embed>`` tag in its HTML file. For information
|
| + about Native Client manifest files, see the :ref:`Technical Overview
|
| + <application_files>`. The SDK includes a script called ``create_nmf.py`` (in
|
| + the ``tools/`` directory) that you can use to generate .nmf files. Run
|
| + "``python create_nmf.py --help``" to see the script's command-line options,
|
| + and look at the Makefiles in the SDK examples to see how to use the script to
|
| + generate a manifest file for modules compiled with either toolchain.
|
| +
|
| + For details on how to use make, see the `GNU 'make' Manual
|
| + <http://www.gnu.org/software/make/manual/make.html>`_.
|
| +
|
| +Libraries and header files provided with the SDK
|
| +================================================
|
| +
|
| +The Native Client SDK includes modified versions of standard toolchain-support
|
| +libraries, such as iberty, nosys, pthread, and valgrind, plus the relevant
|
| +header files.
|
| +
|
| +The libraries are located in the following directories:
|
| +
|
| +* x86 toolchains: toolchain/<platform>_x86_<library>/x86_64-nacl/lib32 and
|
| + /lib64 (for the 32-bit and 64-bit target architectures, respectively)
|
| +* ARM toolchain: toolchain/<platform>_arm_<library>/arm-nacl/lib
|
| +
|
| +For example, on Windows, the libraries for the x86-64 architecture in the
|
| +newlib toolchain are in toolchain/win_x86_newlib/x86_64-nacl/lib64.
|
| +
|
| +The standard gcc libraries are also available, in
|
| +toolchain/<platform>_<architecture>_<library>/lib.
|
| +
|
| +The header files are in:
|
| +
|
| +* x86 toolchains: toolchain/<platform>_x86_<library>/x86_64-nacl/include
|
| +* ARM toolchain: toolchain/<platform>_arm_<library>/arm-nacl/include
|
| +
|
| +The toolchains intentionally leave out some standard libraries and header
|
| +files; in particular, for sandboxing reasons, the SDK doesn't support some
|
| +POSIX-specified items. For example, ``open(2)`` isn't included, and
|
| +``close(2)`` doesn't precisely match the POSIX version.
|
| +
|
| +Many other libraries have been ported for use with Native Client; for more
|
| +information, see the `naclports <http://code.google.com/p/naclports/>`_
|
| +project. If you port an open-source library for your own use, we recommend
|
| +adding it to naclports.
|
| +
|
| +Here are descriptions of some of the Native Client-specific libraries provided
|
| +in the SDK:
|
| +
|
| +libppapi.a
|
| + Implements the Pepper (PPAPI) C interface (needed for all applications that
|
| + use Pepper).
|
| +
|
| +libppapi_cpp.a
|
| + Implements the Pepper (PPAPI) C++ interface.
|
| +
|
| +libpthread.a
|
| + Implements the Native Client pthread interface.
|
| +
|
| +libsrpc.a
|
| + Implements the Native Client RPC layer, and is used to implement the Pepper C
|
| + layer.
|
| +
|
| +libimc.a
|
| + Implements the intermodule communications layer (IMC), which is used to
|
| + implement SRPC, the Native Client RPC library.
|
| +
|
| +libgio.a
|
| + Used to implement Native Client logging and some other features in
|
| + nacl_platform.
|
| +
|
| +libplatform.a
|
| + Provides some platform abstractions, and is used to implement some other
|
| + Native Client libraries.
|
| +
|
| +The top-level /lib directory contains two additional Native Client libraries of
|
| +interest:
|
| +
|
| +libnacl_mounts.a
|
| + Provides a virtual file system that a module can "mount" in a given directory
|
| + tree. Once a module has mounted a file system, it can use standard C library
|
| + file operations: fopen, fread, fwrite, fseek, and fclose. For a list of the
|
| + types of file systems that can be mounted, see
|
| + include/nacl_mounts/nacl_mounts.h. For an example of how to use nacl_mounts,
|
| + see examples/hello_nacl_mounts.
|
| +
|
| +libppapi_main.a
|
| + Provides a familiar C programming environment by letting a module have a
|
| + simple entry point called ppapi_main(), which is similar to the standard C
|
| + main() function, complete with argc and argv[] parameters. This library also
|
| + lets modules use standard C functions such as printf(), fopen(), and
|
| + fwrite(). For details see include/ppapi_main/ppapi_main.h. For an example of
|
| + how to use ppapi_main, see examples/hello_world_stdio.
|
| +
|
| +.. Note::
|
| + :class: note
|
| +
|
| + * 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 `naclports
|
| + <http://code.google.com/p/naclports/>`_, or port the library yourself.
|
| + * 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 \*_LDFLAGS variables in the Makefiles of the SDK
|
| + examples for the order in which specific libraries should be listed.
|
| +
|
| +Troubleshooting
|
| +===============
|
| +
|
| +Some common problems, and how to fix them:
|
| +
|
| +"Undefined reference" error
|
| + An "undefined reference" error may indicate incorrect link order and/or
|
| + missing libraries. For example, if you leave out -lppapi when compiling the
|
| + hello_world example, you'll see a series of undefined reference errors.
|
| +
|
| + 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:
|
| +
|
| + #. Link with the -lnosys flag to provide empty/always-fail versions of
|
| + unsupported system calls. This will at least get you past the link stage.
|
| + #. Find and remove use of the unsupported system calls.
|
| + #. Create your own implementation of the unsupported system calls to do
|
| + something useful for your application.
|
| +
|
| + If your code uses mkdir or other file system calls, you might find nacl-mounts
|
| + useful. Nacl-mounts 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., App Engine or an in-memory filesystem).
|
| +
|
| +Can't find libraries containing necessary symbols
|
| + Here is one way to find the appropriate library for a given symbol::
|
| +
|
| + nm -o toolchain/<platform>_x86_<library>/x86_64-nacl/lib64/*.a | grep <MySymbolName>
|
|
|