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