1 {{+bindTo:partials.standard_nacl_article}}
3 <section id=
"c-tutorial-getting-started-part-2">
4 <span id=
"tutorial2"></span><h1 id=
"c-tutorial-getting-started-part-2"><span id=
"tutorial2"></span>C++ Tutorial: Getting Started (Part
2)
</h1>
5 <div class=
"contents local" id=
"contents" style=
"display: none">
7 <li><a class=
"reference internal" href=
"#overview" id=
"id1">Overview
</a></li>
8 <li><p class=
"first"><a class=
"reference internal" href=
"#using-the-native-client-sdk-build-system" id=
"id2">Using the Native Client SDK build system
</a></p>
10 <li><a class=
"reference internal" href=
"#simplifying-the-makefile" id=
"id3">Simplifying the Makefile
</a></li>
11 <li><a class=
"reference internal" href=
"#choosing-valid-toolchains-and-including-common-mk" id=
"id4">Choosing valid toolchains, and including common.mk
</a></li>
12 <li><a class=
"reference internal" href=
"#configuring-your-project" id=
"id5">Configuring your project
</a></li>
13 <li><a class=
"reference internal" href=
"#build-macros" id=
"id6">Build macros
</a></li>
16 <li><p class=
"first"><a class=
"reference internal" href=
"#making-index-html-work-for-chrome-apps" id=
"id7">Making index.html work for Chrome Apps
</a></p>
17 <ul class=
"small-gap">
18 <li><a class=
"reference internal" href=
"#csp-rules" id=
"id8">CSP rules
</a></li>
19 <li><a class=
"reference internal" href=
"#making-index-html-csp-compliant" id=
"id9">Making index.html CSP-compliant
</a></li>
20 <li><a class=
"reference internal" href=
"#making-index-html-support-different-toolchains-and-configurations" id=
"id10">Making index.html support different toolchains and configurations
</a></li>
23 <li><p class=
"first"><a class=
"reference internal" href=
"#sharing-common-code-with-common-js" id=
"id11">Sharing common code with common.js
</a></p>
24 <ul class=
"small-gap">
25 <li><a class=
"reference internal" href=
"#loading-the-page-and-creating-the-module" id=
"id12">Loading the page and creating the module
</a></li>
28 <li><a class=
"reference internal" href=
"#example-specific-behavior-with-example-js" id=
"id13">Example-specific behavior with example.js
</a></li>
29 <li><a class=
"reference internal" href=
"#compile-the-native-client-module-and-run-the-application-again" id=
"id14">Compile the Native Client module and run the application again
</a></li>
32 </div><h2 id=
"overview">Overview
</h2>
33 <p>This tutorial shows how to convert the finished PNaCl web application from
34 <a class=
"reference internal" href=
"/native-client/devguide/tutorial/tutorial-part1.html"><em>Part
1</em></a> to use the Native Client SDK build system and
35 common JavaScript files. It also demonstrates some techniques to make your web
36 application
<a class=
"reference external" href=
"/apps/contentSecurityPolicy">Content Security Policy (CSP)-compliant
</a>, which is necessary for
<a class=
"reference external" href=
"/apps">Chrome Apps
</a>.
</p>
37 <p>Using the Native Client SDK build system makes it easy to build with all of the
38 SDK toolchains, and switch between the Debug and Release configurations. It
39 also simplifies the makefiles for your project, as we
’ll see in the next
40 section. Finally, it adds some useful commands for
<a class=
"reference internal" href=
"/native-client/sdk/examples.html#running-the-sdk-examples"><em>running
</em></a> and
<a class=
"reference internal" href=
"/native-client/sdk/examples.html#debugging-the-sdk-examples"><em>debugging
</em></a>
42 <p>The finished code for this example can be found in the
43 <code>pepper_$(VERSION)/getting_started/part2
</code> directory in the Native Client SDK
45 <h2 id=
"using-the-native-client-sdk-build-system">Using the Native Client SDK build system
</h2>
46 <p>This section describes how to use the SDK build system. To do so, we
’ll make
47 changes in the makefile. Because the makefile in part1 and part2 are so
48 different, it is easier to start from scratch. Here is the contents of the new
49 makefile. The following sections will describe it in more detail.
</p>
50 <h3 id=
"simplifying-the-makefile">Simplifying the Makefile
</h3>
51 <p>The makefile from part1 only supports one toolchain (PNaCl) and one
52 configuration (Release). It also only supports one source file. It
’s relatively
53 simple, but if we want to add support for multiple toolchains, configurations,
54 source files, or build steps, it would grow increasingly complex. The SDK build
55 system uses a set of variables and macros to make this possible, without
56 significantly increasing the complexity of the makefile.
</p>
57 <p>Here is the new makefile, supporting three toolchains (PNaCl, Newlib NaCl,
58 Glibc NaCl) and two configurations (Debug, Release).
</p>
59 <pre class=
"prettyprint">
60 VALID_TOOLCHAINS := pnacl newlib glibc
62 NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
63 include $(NACL_SDK_ROOT)/tools/common.mk
66 LIBS = ppapi_cpp ppapi
69 SOURCES = hello_tutorial.cc
71 # Build rules generated by macros from common.mk:
73 $(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
75 # The PNaCl workflow uses both an unstripped and finalized/stripped binary.
76 # On NaCl, only produce a stripped binary for Release configs (not Debug).
77 ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
78 $(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
79 $(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
81 $(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
84 $(eval $(call NMF_RULE,$(TARGET),))
86 <h3 id=
"choosing-valid-toolchains-and-including-common-mk">Choosing valid toolchains, and including common.mk
</h3>
87 <p>The makefile begins by specifying the toolchains that are valid for this
88 project. The Native Client SDK build system supports multi-toolchain projects
89 for its examples and libraries, but generally you will choose one toolchain
90 when you begin your project and never change it. Please see the
91 <a class=
"reference internal" href=
"/native-client/overview.html#toolchains"><em>Toolchains section of the Native Client overview
</em></a> for more
93 <p>For this example, we support the
<code>pnacl
</code>,
<code>newlib
</code> and
<code>glibc
</code> toolchains.
</p>
94 <pre class=
"prettyprint">
95 VALID_TOOLCHAINS := pnacl newlib glibc
97 <p>Next, as a convenience, we specify where to find
<code>NACL_SDK_ROOT
</code>. Because
98 this example is located in
<code>pepper_$(VERSION)/getting_started/part2
</code>, the
99 root of the SDK is two directories up.
</p>
100 <pre class=
"prettyprint">
101 NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
105 <div>In your own projects, you can use the absolute path to your installed SDK
106 here. You can also override this default by setting the
<code>NACL_SDK_ROOT
</code>
107 environment variable. See
<a class=
"reference internal" href=
"/native-client/devguide/tutorial/tutorial-part1.html#tutorial-step-5"><em>Step
5 of Part
1 of this tutorial
</em></a> for more details.
</div></blockquote>
110 <p>Next, we include the file
<code>tools/common.mk
</code>. This file provides the
111 functionality for the Native Client SDK build system, including new build rules
112 to compile and link a project, which we
’ll use below.
</p>
113 <pre class=
"prettyprint">
114 include $(NACL_SDK_ROOT)/tools/common.mk
116 <h3 id=
"configuring-your-project">Configuring your project
</h3>
117 <p>After including
<code>tools/common.mk
</code>, we configure the project by specifying its
118 name, the sources and libraries it uses:
</p>
119 <pre class=
"prettyprint">
121 LIBS = ppapi_cpp ppapi
124 SOURCES = hello_tutorial.cc
126 <p>These variable names are not required and not used by the SDK build system;
127 they are only used in the rules described below. By convention, all SDK
128 makefiles use the following variables:
</p>
129 <dl class=
"docutils">
131 <dd>The name of the project to build. This variable determines the name of the
132 library or executable that will be generated. In the above example, we call
133 the target
<code>part2
</code>, which will generate an executable called
134 <code>part2.pexe
</code> for PNaCl. For NaCl toolchains, the executable
’s file name
135 will be given a suffix for its architecture. For example, the ARM executable
136 is called
<code>part2_arm.nexe
</code>.
</dd>
138 <dd>A list of libraries that this executable needs to link against. The library
139 search path is already set up to only look in the directory for the current
140 toolchain and architecture. In this example, we link against
<code>ppapi_cpp
</code>
141 and
<code>ppapi
</code>.
<code>ppapi_cpp
</code> is needed to use the
<a class=
"reference external" href=
"/native-client/pepper_stable/cpp/">Pepper C++ interface
</a>.
<code>ppapi
</code> is needed for communicating
142 with the browser.
</dd>
144 <dd>A list of extra flags to pass to the compiler. In this example, we pass
145 <code>-Wall
</code>, which turns on all warnings.
</dd>
147 <dd>A list of additional flags to pass to the linker. This example does not need
148 any special linker flags, so this variable is omitted.
</dd>
150 <dd>A list of C or C++ sources to compile, separated by spaces. If you have a
151 long list of sources, it may be easier to read if you put each file on its
152 own line, and use
<code>\
</code> as a line-continuation character. Here
’s an example:
</dd>
154 <pre class=
"prettyprint">
160 <h3 id=
"build-macros">Build macros
</h3>
161 <p>For many projects, the following build macros do not need to be changed; they
162 will use the variables we
’ve defined above.
</p>
163 <pre class=
"prettyprint">
164 $(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
166 ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
167 $(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
168 $(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
170 $(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
173 $(eval $(call NMF_RULE,$(TARGET),))
175 <p>The first line defines rules to compile each source in
<code>SOURCES
</code>, using the
176 flags in
<code>CFLAGS
</code>:
</p>
177 <pre class=
"prettyprint">
178 $(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
180 <p>The next six lines define rules to link the object files into one or more
181 executables. When
<code>TOOLCHAIN
</code> is
<code>pnacl
</code>, there is only one executable
182 generated: in the example above,
<code>part2.pexe
</code>. When using a NaCl toolchain,
183 there will be three executables generated, one for each architecture: in the
184 example above,
<code>part2_arm.nexe
</code>,
<code>part2_x86_32.nexe
</code> and
185 <code>part2_x86_64.nexe
</code>.
</p>
186 <p>When
<code>CONFIG
</code> is
<code>Release
</code>, each executable is also stripped to remove
187 debug information and reduce the file size. Otherwise, when the
<code>TOOLCHAIN
</code>
188 is
<code>pnacl
</code>, the workflow involves creating an unstripped binary for debugging
189 and then finalizing it and stripping it for publishing.
</p>
190 <pre class=
"prettyprint">
191 ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
192 $(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
193 $(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
195 $(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
198 <p>Finally, the NMF rule generates a NaCl manifest file (
<code>.nmf
</code>) that references
199 each executable generated in the previous step:
</p>
200 <pre class=
"prettyprint">
201 $(eval $(call NMF_RULE,$(TARGET),))
203 <h2 id=
"making-index-html-work-for-chrome-apps">Making index.html work for Chrome Apps
</h2>
204 <p>This section describes the changes necessary to make the HTML and JavaScript in
205 part1 CSP-compliant. This is required if you want to build a
<a class=
"reference external" href=
"/apps">Chrome App
</a>, but is not necessary if you want to use PNaCl on the open web.
</p>
206 <h3 id=
"csp-rules">CSP rules
</h3>
207 <p><a class=
"reference external" href=
"/apps/contentSecurityPolicy#what">Chrome Apps CSP
</a> restricts you from doing
209 <ul class=
"small-gap">
210 <li>You can’t use inline scripting in your Chrome App pages. The restriction
211 bans both
<code><script
></code> blocks and event handlers (
<code><button onclick=
"...
"></code>).
</li>
212 <li>You can’t reference any external resources in any of your app files (except
213 for video and audio resources). You can’t embed external resources in an
215 <li>You can’t use string-to-JavaScript methods like
<code>eval()
</code> and
<code>new
216 Function()
</code>.
</li>
218 <h3 id=
"making-index-html-csp-compliant">Making index.html CSP-compliant
</h3>
219 <p>To make our application CSP-compliant, we have to remove inline scripting. As
220 described above, we can
’t use inline
<code><script
></code> blocks or event handlers. This
221 is easy to do
—we
’ll just reference some new files from our script tag, and
222 remove all of our inlined scripts:
</p>
223 <pre class=
"prettyprint">
226 <script type=
"text/javascript
" src=
"common.js
"></script
>
227 <script type=
"text/javascript
" src=
"example.js
"></script
>
230 <p><code>common.js
</code> has shared code used by all SDK examples, and is described
231 later in this document.
<code>example.js
</code> is a script that has code specific to
233 <p>We also need to remove the inline event handler on the body tag:
</p>
234 <pre class=
"prettyprint">
235 <body onload=
"pageDidLoad()
">
238 <p>This logic is now handled by
<code>common.js
</code>.
</p>
239 <h3 id=
"making-index-html-support-different-toolchains-and-configurations">Making index.html support different toolchains and configurations
</h3>
240 <p>Finally, there are a few changes to
<code>index.html
</code> that are not necessary for
241 CSP-compliance, but help make the SDK examples more generic.
</p>
242 <p>First, we add some
<a class=
"reference external" href=
"https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes">data attributes
</a>
243 to the body element to specify the name, supported toolchains, supported
244 configurations, and path to the
<code>.nmf
</code> file:
</p>
245 <pre class=
"prettyprint">
246 <body data-name=
"part2
"
247 data-tools=
"newlib glibc pnacl
"
248 data-configs=
"Debug Release
"
249 data-path=
"{tc}/{config}
">
252 <p><code>common.js
</code> will read these data attributes to allow you to load the same
253 example with different toolchains by changing the URL
’s
<a class=
"reference external" href=
"http://en.wikipedia.org/wiki/Query_string">query string
</a>. For example, you can load the
254 glibc Debug version of this example by navigating to
255 <code>index.html?tc=glibc
&config=Debug
</code>. Path URI
’s such as
<code>../
</code>, for example
256 do not work for either the data-path parameter or its corresponding query
258 <p>Next, we remove the
<code>embed
</code> element that is described in HTML. This will be
259 automatically added for us by
<code>common.js
</code>, based on the current
260 toolchain/configuration combination:
</p>
261 <pre class=
"prettyprint">
263 Just as in part1, the
<embed
> element will be wrapped inside the
<div
>
264 element with the id
"listener
". In part1, the embed was specified in HTML,
265 here the common.js module creates a new
<embed
> element and adds it to the
268 <div id=
"listener
"></div
>
270 <h2 id=
"sharing-common-code-with-common-js">Sharing common code with common.js
</h2>
271 <p><code>common.js
</code> contains JavaScript code that each example uses to create a
272 NaCl module, handle messages from that module and other common tasks like
273 displaying the module load status and logging messages. Explaining all of
274 <code>common.js
</code> is outside the scope of this document, but please look at the
275 documentation in that file for more information.
</p>
276 <h3 id=
"loading-the-page-and-creating-the-module">Loading the page and creating the module
</h3>
277 <p>Since we
’ve added
<code><script
></code> tags for
<code>common.js
</code> and
<code>example.js
</code> to the
278 <code>head
</code> element, they will be loaded and executed before the rest of the
279 document has been parsed. As a result, we have to wait for the page to finish
280 loading before we try to create the embed element and add it to the page.
</p>
281 <p>We can do that by calling
<code>addEventListener
</code> and listening for the
282 <code>DOMContentLoaded
</code> event:
</p>
283 <pre class=
"prettyprint">
284 // Listen for the DOM content to be loaded. This event is fired when parsing of
285 // the page's document has finished.
286 document.addEventListener('DOMContentLoaded', function() {
290 <p>Inside this function, we parse the URL query string, and compare that to the
292 <pre class=
"prettyprint">
293 // From https://developer.mozilla.org/en-US/docs/DOM/window.location
295 if (window.location.search.length
> 1) {
296 var pairs = window.location.search.substr(
1).split('
&');
297 for (var key_ix =
0; key_ix
< pairs.length; key_ix++) {
298 var keyValue = pairs[key_ix].split('=');
299 searchVars[unescape(keyValue[
0])] =
300 keyValue.length
> 1 ? unescape(keyValue[
1]) : '';
306 var toolchains = body.dataset.tools.split(' ');
307 var configs = body.dataset.configs.split(' ');
311 var tc = toolchains.indexOf(searchVars.tc) !== -
1 ?
312 searchVars.tc : toolchains[
0];
314 // If the config value is included in the search vars, use that.
315 // Otherwise default to Release if it is valid, or the first value if
316 // Release is not valid.
317 if (configs.indexOf(searchVars.config) !== -
1)
318 var config = searchVars.config;
319 else if (configs.indexOf('Release') !== -
1)
320 var config = 'Release';
322 var config = configs[
0];
324 <p>Then
<code>domContentLoaded
</code> is called, which performs some checks to see if the
325 browser supports Native Client, then creates the NaCl module.
</p>
326 <pre class=
"prettyprint">
327 function domContentLoaded(name, tool, path, width, height, attrs) {
328 updateStatus('Page loaded.');
329 if (!browserSupportsNaCl(tool)) {
331 'Browser does not support NaCl (' + tool + '), or NaCl is disabled');
332 } else if (common.naclModule == null) {
333 updateStatus('Creating embed: ' + tool);
335 // We use a non-zero sized embed to give Chrome space to place the bad
336 // plug-in graphic, if there is a problem.
337 width = typeof width !== 'undefined' ? width :
200;
338 height = typeof height !== 'undefined' ? height :
200;
339 attachDefaultListeners();
340 createNaClModule(name, tool, path, width, height, attrs);
342 // It's possible that the Native Client module onload event fired
343 // before the page's onload event. In this case, the status message
344 // will reflect 'SUCCESS', but won't be displayed. This call will
345 // display the current message.
346 updateStatus('Waiting.');
350 <p><code>attachDefaultListeners
</code> is added before the creation of the module, to make
351 sure that no messages are lost. Note that
<code>window.attachListeners
</code> is also
352 called; this is the way that
<code>common.js
</code> allows each example to configure
353 itself differently. If an example defines the
<code>attachListeners
</code> function, it
354 will be called by
<code>common.js
</code>.
</p>
355 <pre class=
"prettyprint">
356 function attachDefaultListeners() {
357 var listenerDiv = document.getElementById('listener');
358 listenerDiv.addEventListener('load', moduleDidLoad, true);
359 listenerDiv.addEventListener('message', handleMessage, true);
360 listenerDiv.addEventListener('crash', handleCrash, true);
361 if (typeof window.attachListeners !== 'undefined') {
362 window.attachListeners();
366 <p>Finally,
<code>createNaClModule
</code> actually creates the
<code>embed
</code>, and appends it as
367 a child of the element with id
<code>listener
</code>:
</p>
368 <pre class=
"prettyprint">
369 function createNaClModule(name, tool, path, width, height, attrs) {
370 var moduleEl = document.createElement('embed');
371 moduleEl.setAttribute('name', 'nacl_module');
372 moduleEl.setAttribute('id', 'nacl_module');
373 moduleEl.setAttribute('width', width);
374 moduleEl.setAttribute('height', height);
375 moduleEl.setAttribute('path', path);
376 moduleEl.setAttribute('src', path + '/' + name + '.nmf');
380 var mimetype = mimeTypeForTool(tool);
381 moduleEl.setAttribute('type', mimetype);
383 var listenerDiv = document.getElementById('listener');
384 listenerDiv.appendChild(moduleEl);
388 <p>When the module finishes loading, it will dispatch a
<code>load
</code> event, and the
389 event listener function that was registered above (
<code>moduleDidLoad
</code>) will be
390 called. Note that
<code>common.js
</code> allows each example to define a
391 <code>window.moduleDidLoad
</code> function, that will be called here as well.
</p>
392 <pre class=
"prettyprint">
393 function moduleDidLoad() {
394 common.naclModule = document.getElementById('nacl_module');
395 updateStatus('RUNNING');
397 if (typeof window.moduleDidLoad !== 'undefined') {
398 window.moduleDidLoad();
402 <h2 id=
"example-specific-behavior-with-example-js">Example-specific behavior with example.js
</h2>
403 <p>As described in the previous section,
<code>common.js
</code> will call certain functions
404 during the module loading process. This example only needs to respond to two:
405 <code>moduleDidLoad
</code> and
<code>handleMessage
</code>.
</p>
406 <pre class=
"prettyprint">
407 // This function is called by common.js when the NaCl module is
409 function moduleDidLoad() {
410 // Once we load, hide the plugin. In this example, we don't display anything
411 // in the plugin, so it is fine to hide it.
414 // After the NaCl module has loaded, common.naclModule is a reference to the
415 // NaCl module's
<embed
> element.
417 // postMessage sends a message to it.
418 common.naclModule.postMessage('hello');
421 // This function is called by common.js when a message is received from the
423 function handleMessage(message) {
424 var logEl = document.getElementById('log');
425 logEl.textContent += message.data;
428 <h2 id=
"compile-the-native-client-module-and-run-the-application-again">Compile the Native Client module and run the application again
</h2>
430 <li><p class=
"first">Compile the Native Client module by running the
<code>make
</code> command again.
</p>
432 <li><p class=
"first">Start the SDK web server by running
<code>make server
</code>.
</p>
434 <li><p class=
"first">Re-run the application by reloading
<code>http://localhost:
5103/part2
</code> in
436 <p>After Chrome loads the Native Client module, you should see the message sent
442 {{/partials.standard_nacl_article}}