[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / native_client_sdk / src / doc / devguide / devcycle / dynamic-loading.rst
blob3b8dbee328fb128b5c12da6e71d5b64763bbf21e
1 ######################################
2 Dynamic Linking and Loading with glibc
3 ######################################
5 .. contents::
6   :local:
7   :backlinks: none
8   :depth: 2
10 Introduction
11 ============
13 .. Note::
14   :class: caution
16   Portable Native Client currently only supports static linking, and the
17   only C library available for it is newlib. This page is only valid for
18   Native Client, though PNaCl will eventually support some form of
19   dynamic linking.
21 This document describes how to create and deploy dynamically linked and loaded
22 applications with the glibc library in the Native Client SDK. Before reading
23 this document, we recommend reading :doc:`Building Native Client Modules
24 <building>`
26 .. _c_libraries:
28 C standard libraries: glibc and newlib
29 --------------------------------------
31 The Native Client SDK comes with two C standard libraries --- glibc and
32 newlib. These libraries are described in the table below.
34 +--------+----------+-------------+--------------------------------------------+
35 | Library| Linking  | License     | Description                                |
36 +========+==========+=============+============================================+
37 | glibc  | dynamic  | GNU Lesser  | glibc is the GNU implementation of the     |
38 |        | or static| General     | POSIX_ standard runtime library for the C  |
39 |        |          | Public      | programming language. Designed for         |
40 |        |          | License     | portability and performance, glibc is one  |
41 |        |          | (LGPL)      | of the most popular implementations of the |
42 |        |          |             | C library. It is comprised of a set of     |
43 |        |          |             | interdependent libraries including libc,   |
44 |        |          |             | libpthreads, libdl, and others. For        |
45 |        |          |             | documentation, FAQs, and additional        |
46 |        |          |             | information about glibc, see GLIBC_        |
47 +--------+----------+-------------+--------------------------------------------+
48 | newlib | static   | Berkeley    | newlib is a C library intended for use in  |
49 |        |          | Software    | embedded systems. Like glibc, newlib is a  |
50 |        |          | Distribution| conglomeration of several library parts.   |
51 |        |          | (BSD) type  | It is available for use under BSD-type free|
52 |        |          | free        | software licenses, which generally makes it|
53 |        |          | software    | more suitable to link statically in        |
54 |        |          | licenses    | commercial, closed-source applications. For|
55 |        |          |             | documentation, FAQs, and additional        |
56 |        |          |             | information about newlib, see the newlib_  |
57 |        |          |             | documentation.                             |
58 +--------+----------+-------------+--------------------------------------------+
60 For proprietary (closed-source) applications, your options are to either
61 statically link to newlib, or dynamically link to glibc. We recommend
62 dynamically linking to glibc, for a couple of reasons:
64 * The glibc library is widely distributed (it's included in Linux
65   distributions), and as such it's mature, hardened, and feature-rich. Your
66   code is more likely to compile out-of-the-box with glibc.
68 * Dynamic loading can provide a big performance benefit for your application if
69   you can structure the application to defer loading of code that's not needed
70   for initial interaction with the user. It takes some work to put such code in
71   shared libraries and to load the libraries at runtime, but the payoff is
72   usually worth it. In future releases, Chrome may also support caching of
73   common dynamically linked libraries such as libc.so between applications.
74   This could significantly reduce download size and provide a further potential
75   performance benefit (for example, the hello_world example would only require
76   downloading a .nexe file that's on the order of 30KB, rather than a .nexe
77   file and several libraries, which are on the order of 1.5MB).
79 Native Client support for dynamic linking and loading is based on glibc. Thus,
80 **if your Native Client application must dynamically link and load code (e.g.,
81 due to licensing considerations), we recommend that you use the glibc
82 library.**
84 .. Note::
85   :class: note
87   **Notes:**
89   * **None of the above constitutes legal advice, or a description of the legal
90     obligations you need to fulfill in order to be compliant with the LGPL or
91     newlib licenses. The above description is only a technical explanation of
92     the differences between newlib and glibc, and the choice you must make
93     between the two libraries.**
95   * Static linking with glibc is rarely used. Use this feature with caution.
97   * The standard C++ runtime in Native Client is provided by libstdc++; this
98     library is independent from and layered on top of glibc. Because of
99     licensing restrictions, libstdc++ must be statically linked for commercial
100     uses, even if the rest of an application is dynamically linked.
102 SDK toolchains
103 --------------
105 The Native Client SDK contains multiple toolchains, which are differentiated by
106 :ref:`target architecture <target_architectures>` and C library:
108 =================== ========= ===============================
109 Target architecture C library Toolchain directory
110 =================== ========= ===============================
111 x86                 newlib    toolchain/<platform>_x86_newlib
112 x86                 glibc     toolchain/<platform>_x86_glibc
113 ARM                 newlib    toolchain/<platform>_arm_newlib
114 PNaCl               newlib    toolchain/<platform>_pnacl
115 =================== ========= ===============================
117 In the directories listed above, <platform> is the platform of your development
118 machine (i.e., win, mac, or linux). For example, in the Windows SDK, the x86
119 toolchain that uses glibc is in ``toolchain/win_x86_glibc``.
121 .. Note::
122   :class: note
124   **Note:** The ARM and PNaCl toolchains are currently restricted to newlib.
126 To use the glibc library and dynamic linking in your application, you **must**
127 use a glibc toolchain. (Currently the only glibc toolchain is
128 ``<platform>_x86_glibc``.) Note that you must build all code in your application
129 with one toolchain. Code from multiple toolchains cannot be mixed.
131 Specifying and delivering shared libraries
132 ------------------------------------------
134 One significant difference between newlib and glibc applications is that glibc
135 applications must explicitly list and deploy the shared libraries that they
136 use.
138 In a desktop environment, when the user launches a dynamically linked
139 application, the operating system's program loader determines the set of
140 libraries the application requires by reading explicit inter-module
141 dependencies from executable file headers, and loads the required libraries
142 into the address space of the application process. Typically the required
143 libraries will have been installed on the system as a part of the application's
144 installation process. Often the desktop application developer doesn't know or
145 think about the libraries that are required by an application, as those details
146 are taken care of by the user's operating system.
148 In the Native Client sandbox, dynamic linking can't rely in the same way on the
149 operating system or the local file system. Instead, the application developer
150 must identify the set of libraries that are required by an application, list
151 those libraries in a Native Client :ref:`manifest file <manifest_file>`, and
152 deploy the libraries along with the application. Instructions for how to build
153 a dynamically linked Native Client application, generate a Native Client
154 manifest (.nmf) file, and deploy an application are provided below.
156 Building a dynamically linked application
157 =========================================
159 Applications built with the glibc toolchain will by dynamically linked by
160 default. Application that load shared libraries at runtime using ``dlopen()``
161 must link with the libdl library (``-ldl``).
163 Like other gcc-based toolchains building a dynamic library for NaCl is normally
164 done by linking with the ``-shared`` flag and compiling with the ``-fPIC`` flag.
165 The SDK build system will do this automatically when the ``SO_RULE`` Makefile
166 rule is used.
168 The Native Client SDK includes an example that demonstrates how to build a
169 shared library, and how to use the ``dlopen()`` interface to load that library
170 at runtime (after the application is already running). Many applications load
171 and link shared libraries at launch rather than at runtime, and hence do not
172 use the ``dlopen()`` interface. The SDK example is nevertheless instructive, as
173 it demonstrates how to build Native Client modules (.nexe files) and shared
174 libraries (.so files) with the x86 glibc toolchain, and how to generate a
175 Native Client manifest file for glibc applications.
177 The SDK example, located in ``examples/tutorial/dlopen``, includes three C++
178 files:
180 eightball.cc
181   This file implements the function ``Magic8Ball()``, which is used to provide
182   whimsical answers to user questions. This file is compiled into a shared
183   library called ``libeightball.so``. This library gets included in the
184   .nmf file and is therefore directly loadable with ``dlopen()``.
186 reverse.cc
187   This file implements the function ``Reverse()``, which returns reversed
188   copies of strings that are passed to it. This file is compiled into a shared
189   library called ``libreverse.so``. This library is **not** included in the
190   .nmf file and is loaded via an http mount using the :ref:`nacl_io library
191   <nacl_io>`.
193 dlopen.cc
194   This file implements the Native Client module, which loads the two shared
195   libraries and handles communcation with with JavaScript. The file is compiled
196   into a Native Client executable (.nexe).
198 Run ``make`` in the dlopen directory to see the commands the Makefile executes
199 to build x86 32-bit and 64-bit .nexe and .so files, and to generate a .nmf
200 file. These commands are described below.
202 .. Note::
203   :class: note
205   **Note:** The Makefiles for most of the examples in the SDK build the
206   examples using multiple toolchains (x86 newlib, x86 glibc, ARM, and PNaCl).
207   With a few exceptions (listed in the :ref:`Release Notes
208   <sdk-release-notes>`), running "make" in each example's directory builds
209   multiple versions of the example using the SDK toolchains. The dlopen example
210   is one of those exceptions â€“ it is only built with the x86 glibc toolchain,
211   as that is currently the only toolchain that supports glibc and thus dynamic
212   linking and loading. Take a look at the example Makefiles and the generated
213   .nmf files for details on how to build dynamically linked applications.
215 .. _dynamic_loading_manifest:
217 Generating a Native Client manifest file for a dynamically linked application
218 =============================================================================
220 The Native Client manifest file specifies the name of the executable to run
221 and must also specify any shared libraries that the application directly
222 depends on. For indirect dependencies (such as libraries opened via
223 ``dlopen()``) it is also convenient to list libraries in the manifest file.
224 However it is possile to load arbitrary shared libraries at runtime that
225 are not mentioned in the manifest by using the `nacl_io library <nacl_io>`_
226 to mount a filesystem that contains the shared libraries which will then
227 allow ``dlopen()`` to access them.
229 In this example we demonstrate both loading directly from via the manifest
230 file (``libeightball.so``) and loading indirectly via a http mount
231 (``libreverse.so``).
233 Take a look at the manifest file in the dlopen example to see how
234 a glibc-style manifest file is structured. (Run ``make`` in the dlopen directory to
235 generate the manifest file if you haven't done so already.) Here is an excerpt
236 from ``dlopen.nmf``::
238   {
239     "files": {
240       "libeightball.so": {
241         "x86-64": {
242           "url": "lib64/libeightball.so"
243         },
244         "x86-32": {
245           "url": "lib32/libeightball.so"
246         }
247       },
248       "libstdc++.so.6": {
249         "x86-64": {
250           "url": "lib64/libstdc++.so.6"
251         },
252         "x86-32": {
253           "url": "lib32/libstdc++.so.6"
254         }
255       },
256       "libppapi_cpp.so": {
257         "x86-64": {
258           "url": "lib64/libppapi_cpp.so"
259         },
260         "x86-32": {
261           "url": "lib32/libppapi_cpp.so"
262         }
263       },
264   ... etc.
266 In most cases, you can use the ``create_nmf.py`` script in the SDK to generate
267 a manifest file for your application. The script is located in the tools
268 directory (e.g. ``pepper_28/tools``).
270 The Makefile in the dlopen example generates the manifest automatically using
271 the ``NMF_RULE`` provided by the SDK build system. Running ``make V=1`` will
272 show the full command line which is used to generate the nmf::
274   create_nmf.py -o dlopen.nmf glibc/Release/dlopen_x86_32.nexe \
275      glibc/Release/dlopen_x86_64.nexe glibc/Release/libeightball_x86_32.so \
276      glibc/Release/libeightball_x86_64.so  -s ./glibc/Release \
277      -n libeightball_x86_32.so,libeightball.so \
278      -n libeightball_x86_64.so,libeightball.so
280 Run python ``create_nmf.py --help`` to see a full description of the command-line
281 flags. A few of the important flags are described below.
283 ``-s`` *directory*
284   use *directory* to stage libraries (libraries are added to ``lib32`` and
285   ``lib64`` subfolders)
287 ``-L`` *directory*
288   add *directory* to the library search path. The default search path
289   already includes the toolchain and SDK libraries directories.
291 .. Note::
292   :class: note
294   **Note:** The ``create_nmf`` script can only automatically detect explicit
295   shared library dependencies (for example, dependencies specified with the -l
296   flag for the compiler/linker). If you want to include libraries that you
297   intend to dlopen() at runtime you must explcitly list them in your call to
298   ``create_nmf``.
300 As an alternative to using ``create_nmf``, it is possible to manually calculate
301 the list of shared library dependencies using tools such as ``objdump_``.
303 Deploying a dynamically linked application
304 ==========================================
306 As described above, an application's manifest file must explicitly list all the
307 executable code modules that the application directly depends on, including
308 modules from the application itself (.nexe and .so files), modules from the
309 Native Client SDK (e.g., libppapi_cpp.so), and perhaps also modules from
310 `naclports <http://code.google.com/p/naclports/>`_ or from
311 `middleware systems <../../community/middleware>`_ that
312 the application uses. You must provide all of those modules as part of the
313 application deployment process.
315 As explained in :doc:`Distributing Your Application
316 <../distributing>`, there are two basic ways to deploy an application:
318 * **hosted application:** all modules are hosted together on a web server of
319   your choice
321 * **packaged application:** all modules are packaged into one file, hosted in
322   the Chrome Web Store, and downloaded to the user's machine
324 You must deploy all the modules listed in your application's manifest file for
325 either the hosted application or the packaged application case. For hosted
326 applications, you must upload the modules to your web server. For packaged
327 applications, you must include the modules in the application's Chrome Web
328 Store .crx file. Modules should use URLs/names that are consistent with those
329 in the Native Client manifest file, and be named relative to the location of
330 the manifest file. Remember that some of the libraries named in the manifest
331 file may be located in directories you specified with the -L option to
332 ``create_nmf.py``. You are free to rename/rearrange files and directories
333 referenced by the Native Client manifest file, so long as the modules are
334 available in the locations indicated by the manifest file. If you move or
335 rename modules, it may be easier to re-run ``create_nmf.py`` to generate a new
336 manifest file rather than edit the original manifest file. For hosted
337 applications, you can check for name mismatches during testing by watching the
338 request log of the web server hosting your test deployment.
340 Opening a shared library at runtime
341 ===================================
343 Native Client supports a version of the POSIX standard ``dlopen()`` interface
344 for opening libraries explicitly, after an application is already running.
345 Calling ``dlopen()`` may cause a library download to occur, and automatically
346 loads all libraries that are required by the named library.
348 .. Note::
349   :class: note
351   **Caution:** Since ``dlopen()`` can potentially block, you must initially
352   call ``dlopen()`` off your application's main thread. Initial calls to
353   ``dlopen()`` from the main thread will always fail in the current
354   implementation of Native Client.
356 The best practice for opening libraries with ``dlopen()`` is to use a worker
357 thread to pre-load libraries asynchronously during initialization of your
358 application, so that the libraries are available when they're needed. You can
359 call ``dlopen()`` a second time when you need to use a library -- per the
360 specification, subsequent calls to ``dlopen()`` return a handle to the
361 previously loaded library. Note that you should only call ``dlclose()`` to
362 close a library when you no longer need the library; otherwise, subsequent
363 calls to ``dlopen()`` could cause the library to be fetched again.
365 The dlopen example in the SDK demonstrates how to open a shared libraries
366 at runtime. To reiterate, the example includes three C++ files:
368 * ``eightball.cc``: this is the shared library that implements the function
369   ``Magic8Ball()`` (this file is compiled into libeightball.so)
370 * ``reverse.cc``: this is the shared library that implements the function
371   ``Reverse()`` (this file is compiled into libreverse.so)
372 * ``dlopen.cc``: this is the Native Client module that loads the shared libraries
373   and makes calls to ``Magic8Ball()`` and ``Reverse()`` in response to requests
374   from JavaScript.
376 When the Native Client module starts, it kicks off a worker thread that calls
377 ``dlopen()`` to load the two shared libraries. Once the module has a handle to
378 the library, it fetches the addresses of the ``Magic8Ball()`` and ``Reverse()``
379 functions using ``dlsym()``. When a user types in a query and clicks the 'ASK!'
380 button, the module calls ``Magic8Ball()`` to generate an answer, and returns
381 the result to the user. Likewise when the user clicks the 'Reverse' button
382 it calls the ``Reverse()`` function to reverse the string.
384 Troubleshooting
385 ===============
387 If your .nexe isn't loading, the best place to look for information that can
388 help you troubleshoot the JavaScript console and standard output from Chrome.
389 See :ref:`Debugging <devcycle-debugging>` for more information.
391 Here are a few common error messages and explanations of what they mean:
393 **/main.nexe: error while loading shared libraries: /main.nexe: failed to allocate code and data space for executable**
394   The .nexe may not have been compiled correctly (e.g., the .nexe may be
395   statically linked). Try cleaning and recompiling with the glibc toolchain.
397 **/main.nexe: error while loading shared libraries: libpthread.so.xxxx: cannot open shared object file: Permission denied**
398   (xxxx is a version number, for example, 5055067a.) This error can result from
399   having the wrong path in the .nmf file. Double-check that the path in the
400   .nmf file is correct.
402 **/main.nexe: error while loading shared libraries: /main.nexe: cannot open shared object file: No such file or directory**
403   If there are no obvious problems with your main.nexe entry in the .nmf file,
404   check where main.nexe is being requested from. Use Chrome's Developer Tools:
405   Click the menu icon |menu-icon|, select Tools > Developer Tools, click the
406   Network tab, and look at the path in the Name column.
408 **NaCl module load failed: ELF executable text/rodata segment has wrong starting address**
409   This error happens when using a newlib-style .nmf file instead of a
410   glibc-style .nmf file. Make sure you build your application with the glic
411   toolchain, and use the create_nmf.py script to generate your .nmf file.
413 **NativeClient: NaCl module load failed: Nexe crashed during startup**
414   This error message indicates that a module crashed while being loaded. You
415   can determine which module crashed by looking at the Network tab in Chrome's
416   Developer Tools (see above). The module that crashed will be the last one
417   that was loaded.
419 **/lib/main.nexe: error while loading shared libraries: /lib/main.nexe: only ET_DYN and ET_EXEC can be loaded**
420   This error message indicates that there is an error with the .so files listed
421   in the .nmf file -- either the files are the wrong type or kind, or an
422   expected library is missing.
424 **undefined reference to 'dlopen' collect2: ld returned 1 exit status**
425   This is a linker ordering problem that usually results from improper ordering
426   of command line flags when linking. Reconfigure your command line string to
427   list libraries after the -o flag.
429 .. |menu-icon| image:: /images/menu-icon.png
430 .. _objdump: http://en.wikipedia.org/wiki/Objdump
431 .. _GLIBC: http://www.gnu.org/software/libc/index.html
432 .. _POSIX: http://en.wikipedia.org/wiki/POSIX
433 .. _newlib: http://sourceware.org/newlib/