Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1825)

Unified Diff: native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/tutorial/tutorial-part2.html

Issue 140993006: [NaCl SDK Docs] Check in the generated NaCl SDK Documentation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: try without pepper_{dev,beta,stable} Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/tutorial/tutorial-part2.html
diff --git a/native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/tutorial/tutorial-part2.html b/native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/tutorial/tutorial-part2.html
new file mode 100644
index 0000000000000000000000000000000000000000..edcaf74b5b7f10e0d3134a637c0f3a6bbb8d7ac6
--- /dev/null
+++ b/native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/tutorial/tutorial-part2.html
@@ -0,0 +1,439 @@
+{{+bindTo:partials.standard_nacl_article}}
+
+<section id="c-tutorial-getting-started-part-2">
+<span id="tutorial2"></span><h1 id="c-tutorial-getting-started-part-2"><span id="tutorial2"></span>C++ Tutorial: Getting Started (Part 2)</h1>
+<div class="contents local topic" id="contents">
+<ul class="small-gap">
+<li><a class="reference internal" href="#overview" id="id1">Overview</a></li>
+<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>
+<ul class="small-gap">
+<li><a class="reference internal" href="#simplifying-the-makefile" id="id3">Simplifying the Makefile</a></li>
+<li><a class="reference internal" href="#choosing-valid-toolchains-and-including-common-mk" id="id4">Choosing valid toolchains, and including common.mk</a></li>
+<li><a class="reference internal" href="#configuring-your-project" id="id5">Configuring your project</a></li>
+<li><a class="reference internal" href="#build-macros" id="id6">Build macros</a></li>
+</ul>
+</li>
+<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>
+<ul class="small-gap">
+<li><a class="reference internal" href="#csp-rules" id="id8">CSP rules</a></li>
+<li><a class="reference internal" href="#making-index-html-csp-compliant" id="id9">Making index.html CSP-compliant</a></li>
+<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>
+</ul>
+</li>
+<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>
+<ul class="small-gap">
+<li><a class="reference internal" href="#loading-the-page-and-creating-the-module" id="id12">Loading the page and creating the module</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#example-specific-behavior-with-example-js" id="id13">Example-specific behavior with example.js</a></li>
+</ul>
+</div>
+<section id="overview">
+<h2 id="overview">Overview</h2>
+<p>This tutorial shows how to convert the finished PNaCl web application from
+<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
+common JavaScript files. It also demonstrates some techniques to make your
+web application <cite>Content Security Policy (CSP)-compliant
+&lt;http://developer.chrome.com/apps/contentSecurityPolicy.html&gt;</cite>, which is
+necessary for <a class="reference external" href="https://developer.chrome.com/apps/about_apps.html">Chrome Apps</a>.</p>
+<p>Using the Native Client SDK build system makes it easy to build with all of the
+SDK toolchains, and switch between the Debug and Release configurations. It
+also simplifies the makefiles for your project, as we&#8217;ll see in the next
+section. Finally, it adds some useful commands for <a class="reference internal" href="/native-client/sdk/examples.html#id1"><em>running</em></a> and <a class="reference internal" href="/native-client/sdk/examples.html#debugging-the-sdk-examples"><em>debugging</em></a>
+your application.</p>
+<p>The finished code for this example can be found in the
+<code>pepper_$(VERSION)/getting_started/part2</code> directory in the Native Client SDK
+download.</p>
+</section><section id="using-the-native-client-sdk-build-system">
+<h2 id="using-the-native-client-sdk-build-system">Using the Native Client SDK build system</h2>
+<p>This section describes how to use the SDK build system. To do so, we&#8217;ll make
+changes in the makefile. Because the makefile in part1 and part2 are so
+different, it is easier to start from scratch. Here is the contents of the new
+makefile. The following sections will describe it in more detail.</p>
+<section id="simplifying-the-makefile">
+<h3 id="simplifying-the-makefile">Simplifying the Makefile</h3>
+<p>The makefile from part1 only supports one toolchain (PNaCl) and one
+configuration (Release). It also only supports one source file. It&#8217;s relatively
+simple, but if we want to add support for multiple toolchains, configurations,
+source files, or build steps, it would grow increasingly complex. The SDK build
+system uses a set of variables and macros to make this possible, without
+significantly increasing the complexity of the makefile.</p>
+<p>Here is the new makefile, supporting three toolchains (PNaCl, Newlib NaCl,
+Glibc NaCl) and two configurations (Debug, Release).</p>
+<pre class="prettyprint">
+VALID_TOOLCHAINS := pnacl newlib glibc
+
+NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
+include $(NACL_SDK_ROOT)/tools/common.mk
+
+TARGET = part2
+LIBS = ppapi_cpp ppapi
+
+CFLAGS = -Wall
+SOURCES = hello_tutorial.cc
+
+# Build rules generated by macros from common.mk:
+
+$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
+
+ifeq ($(CONFIG),Release)
+$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
+$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
+else
+$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
+endif
+
+$(eval $(call NMF_RULE,$(TARGET),))
+</pre>
+</section><section id="choosing-valid-toolchains-and-including-common-mk">
+<h3 id="choosing-valid-toolchains-and-including-common-mk">Choosing valid toolchains, and including common.mk</h3>
+<p>The makefile begins by specifying the toolchains that are valid for this
+project. The Native Client SDK build system supports multi-toolchain projects
+for its examples and libraries, but generally you will choose one toolchain
+when you begin your project and never change it. Please see the
+<a class="reference internal" href="/native-client/overview.html#toolchains"><em>Toolchains section of the Native Client overview</em></a> for more
+information.</p>
+<p>For this example, we support the <code>pnacl</code>, <code>newlib</code> and <code>glibc</code> toolchains.</p>
+<pre class="prettyprint">
+VALID_TOOLCHAINS := pnacl newlib glibc
+</pre>
+<p>Next, as a convenience, we specify where to find <code>NACL_SDK_ROOT</code>. Because
+this example is located in <code>pepper_$(VERSION)/getting_started/part2</code>, the
+root of the SDK is two directories up.</p>
+<pre class="prettyprint">
+NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
+</pre>
+<aside class="note">
+<blockquote>
+<div>In your own projects, you can use the absolute path to your installed SDK
+here. You can also override this default by setting the <code>NACL_SDK_ROOT</code>
+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>
+
+</aside>
+<p>Next, we include the file <code>tools/common.mk</code>. This file provides the
+functionality for the Native Client SDK build system, including new build rules
+to compile and link a project, which we&#8217;ll use below.</p>
+<pre class="prettyprint">
+include $(NACL_SDK_ROOT)/tools/common.mk
+</pre>
+</section><section id="configuring-your-project">
+<h3 id="configuring-your-project">Configuring your project</h3>
+<p>After including <code>tools/common.mk</code>, we configure the project by specifying its
+name, the sources and libraries it uses:</p>
+<pre class="prettyprint">
+TARGET = part2
+LIBS = ppapi_cpp ppapi
+
+CFLAGS = -Wall
+SOURCES = hello_tutorial.cc
+</pre>
+<p>These variable names are not required and not used by the SDK build system;
+they are only used in the rules described below. By convention, all SDK
+makefiles use the following variables:</p>
+<dl class="docutils">
+<dt>TARGET</dt>
+<dd>The name of the project to build. This variable determines the name of the
+library or executable that will be generated. In the above example, we call
+the target <code>part2</code>, which will generate an executable called
+<code>part2.pexe</code> for PNaCl. For NaCl toolchains, the executable&#8217;s file name
+will be given a suffix for its architecture. For example, the ARM executable
+is called <code>part2_arm.nexe</code>.</dd>
+<dt>LIBS</dt>
+<dd>A list of libraries that this executable needs to link against. The library
+search path is already set up to only look in the directory for the current
+toolchain and architecture. In this example, we link against <code>ppapi_cpp</code>
+and <code>ppapi</code>. <code>ppapi_cpp</code> is needed to use the <a class="reference external" href="https://developers.google.com/native-client/peppercpp/">Pepper C++ interface</a>. <code>ppapi</code> is
+needed for communicating with the browser.</dd>
+<dt>CFLAGS</dt>
+<dd>A list of extra flags to pass to the compiler. In this example, we pass
+<code>-Wall</code>, which turns on all warnings.</dd>
+<dt>LDFLAGS</dt>
+<dd>A list of additional flags to pass to the linker. This example does not need
+any special linker flags, so this variable is omitted.</dd>
+<dt>SOURCES</dt>
+<dd>A list of C or C++ sources to compile, separated by spaces. If you have a
+long list of sources, it may be easier to read if you put each file on its
+own line, and use <code>\</code> as a line-continuation character. Here&#8217;s an example:</dd>
+</dl>
+<pre class="prettyprint">
+SOURCES = foo.cc \
+ bar.cc \
+ baz.cc \
+ quux.cc
+</pre>
+</section><section id="build-macros">
+<h3 id="build-macros">Build macros</h3>
+<p>For many projects, the following build macros do not need to be changed; they
+will use the variables we&#8217;ve defined above.</p>
+<pre class="prettyprint">
+$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
+
+ifeq ($(CONFIG),Release)
+$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
+$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
+else
+$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
+endif
+
+$(eval $(call NMF_RULE,$(TARGET),))
+</pre>
+<p>The first line defines rules to compile each source in <code>SOURCES</code>, using the
+flags in <code>CFLAGS</code>:</p>
+<pre class="prettyprint">
+$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
+</pre>
+<p>The next six lines define rules to link the object files into one or more
+executables. When <code>TOOLCHAIN</code> is <code>pnacl</code>, there is only one executable
+generated: in the example above, <code>part2.pexe</code>. When using a NaCl toolchain,
+there will be three executables generated, one for each architecture: in the
+example above, <code>part2_arm.nexe</code>, <code>part2_x86_32.nexe</code> and
+<code>part2_x86_64.nexe</code>.</p>
+<p>When <code>CONFIG</code> is <code>Release</code>, each executable is also stripped to remove
+debug information and reduce the file size:</p>
+<pre class="prettyprint">
+ifeq ($(CONFIG),Release)
+$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
+$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
+else
+$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
+endif
+</pre>
+<p>Finally, the NMF rule generates a NaCl manifest file (<code>.nmf</code>) that references
+each executable generated in the previous step:</p>
+<pre class="prettyprint">
+$(eval $(call NMF_RULE,$(TARGET),))
+</pre>
+</section></section><section id="making-index-html-work-for-chrome-apps">
+<h2 id="making-index-html-work-for-chrome-apps">Making index.html work for Chrome Apps</h2>
+<p>This section describes the changes necessary to make the HTML and JavaScript
+in part1 CSP-compliant. This is required if you want to build a <a class="reference external" href="https://developer.chrome.com/apps/about_apps.html">Chrome App</a>, but is not necessary
+if you want to use PNaCl on the open web.</p>
+<section id="csp-rules">
+<h3 id="csp-rules">CSP rules</h3>
+<p><a class="reference external" href="http://developer.chrome.com/apps/contentSecurityPolicy.html#what">Chrome Apps CSP</a>
+restricts you from doing the following:</p>
+<ul class="small-gap">
+<li>You can’t use inline scripting in your Chrome App pages. The restriction
+bans both <code>&lt;script&gt;</code> blocks and event handlers (<code>&lt;button onclick=&quot;...&quot;&gt;</code>).</li>
+<li>You can’t reference any external resources in any of your app files (except
+for video and audio resources). You can’t embed external resources in an
+iframe.</li>
+<li>You can’t use string-to-JavaScript methods like <code>eval()</code> and <code>new
+Function()</code>.</li>
+</ul>
+</section><section id="making-index-html-csp-compliant">
+<h3 id="making-index-html-csp-compliant">Making index.html CSP-compliant</h3>
+<p>To make our application CSP-compliant, we have to remove inline scripting. As
+described above, we can&#8217;t use inline <code>&lt;script&gt;</code> blocks or event handlers. This
+is easy to do&#8212;we&#8217;ll just reference some new files from our script tag, and
+remove all of our inlined scripts:</p>
+<pre class="prettyprint">
+&lt;head&gt;
+ ...
+ &lt;script type=&quot;text/javascript&quot; src=&quot;common.js&quot;&gt;&lt;/script&gt;
+ &lt;script type=&quot;text/javascript&quot; src=&quot;example.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+</pre>
+<p><code>common.js</code> has shared code used by all SDK examples, and is described
+later in this document. <code>example.js</code> is a script that has code specific to
+this example.</p>
+<p>We also need to remove the inline event handler on the body tag:</p>
+<pre class="prettyprint">
+&lt;body onload=&quot;pageDidLoad()&quot;&gt;
+...
+</pre>
+<p>This logic is now handled by <code>common.js</code>.</p>
+</section><section id="making-index-html-support-different-toolchains-and-configurations">
+<h3 id="making-index-html-support-different-toolchains-and-configurations">Making index.html support different toolchains and configurations</h3>
+<p>Finally, there are a few changes to <code>index.html</code> that are not necessary for
+CSP-compliance, but help make the SDK examples more generic.</p>
+<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>
+to the body element to specify the name, supported toolchains, supported
+configurations, and path to the <code>.nmf</code> file:</p>
+<pre class="prettyprint">
+&lt;body data-name=&quot;part2&quot;
+ data-tools=&quot;newlib glibc pnacl&quot;
+ data-configs=&quot;Debug Release&quot;
+ data-path=&quot;{tc}/{config}&quot;&gt;
+...
+</pre>
+<p><code>common.js</code> will read these data attributes to allow you to load the same
+example with different toolchains by changing the URL&#8217;s <a class="reference external" href="http://en.wikipedia.org/wiki/Query_string">query string</a>. For example, you can load the
+glibc Debug version of this example by navigating to
+<code>index.html?tc=glibc&amp;config=Debug</code>.</p>
+<p>Next, we remove the <code>embed</code> element that is described in HTML. This will be
+automatically added for us by <code>common.js</code>, based on the current
+toolchain/configuration combination:</p>
+<pre class="prettyprint">
+&lt;!--
+Just as in part1, the &lt;embed&gt; element will be wrapped inside the &lt;div&gt;
+element with the id &quot;listener&quot;. In part1, the embed was specified in HTML,
+here the common.js module creates a new &lt;embed&gt; element and adds it to the
+&lt;div&gt; for us.
+--&gt;
+&lt;div id=&quot;listener&quot;&gt;&lt;/div&gt;
+</pre>
+</section></section><section id="sharing-common-code-with-common-js">
+<h2 id="sharing-common-code-with-common-js">Sharing common code with common.js</h2>
+<p><code>common.js</code> contains JavaScript code that each example uses to create a
+NaCl module, handle messages from that module and other common tasks like
+displaying the module load status and logging messages. Explaining all of
+<code>common.js</code> is outside the scope of this document, but please look at the
+documentation in that file for more information.</p>
+<section id="loading-the-page-and-creating-the-module">
+<h3 id="loading-the-page-and-creating-the-module">Loading the page and creating the module</h3>
+<p>Since we&#8217;ve added <code>&lt;script&gt;</code> tags for <code>common.js</code> and <code>example.js</code> to the
+<code>head</code> element, they will be loaded and executed before the rest of the
+document has been parsed. As a result, we have to wait for the page to finish
+loading before we try to create the embed element and add it to the page.</p>
+<p>We can do that by calling <code>addEventListener</code> and listening for the
+<code>DOMContentLoaded</code> event:</p>
+<pre class="prettyprint">
+// Listen for the DOM content to be loaded. This event is fired when parsing of
+// the page's document has finished.
+document.addEventListener('DOMContentLoaded', function() {
+ ...
+});
+</pre>
+<p>Inside this function, we parse the URL query string, and compare that to the
+data attributes:</p>
+<pre class="prettyprint">
+// From https://developer.mozilla.org/en-US/docs/DOM/window.location
+var searchVars = {};
+if (window.location.search.length &gt; 1) {
+ var pairs = window.location.search.substr(1).split('&amp;');
+ for (var key_ix = 0; key_ix &lt; pairs.length; key_ix++) {
+ var keyValue = pairs[key_ix].split('=');
+ searchVars[unescape(keyValue[0])] =
+ keyValue.length &gt; 1 ? unescape(keyValue[1]) : '';
+ }
+}
+
+...
+
+var toolchains = body.dataset.tools.split(' ');
+var configs = body.dataset.configs.split(' ');
+
+...
+
+var tc = toolchains.indexOf(searchVars.tc) !== -1 ?
+ searchVars.tc : toolchains[0];
+
+// If the config value is included in the search vars, use that.
+// Otherwise default to Release if it is valid, or the first value if
+// Release is not valid.
+if (configs.indexOf(searchVars.config) !== -1)
+ var config = searchVars.config;
+else if (configs.indexOf('Release') !== -1)
+ var config = 'Release';
+else
+ var config = configs[0];
+</pre>
+<p>Then <code>domContentLoaded</code> is called, which performs some checks to see if the
+browser supports Native Client, then creates the NaCl module.</p>
+<pre class="prettyprint">
+function domContentLoaded(name, tool, path, width, height, attrs) {
+ updateStatus('Page loaded.');
+ if (!browserSupportsNaCl(tool)) {
+ updateStatus(
+ 'Browser does not support NaCl (' + tool + '), or NaCl is disabled');
+ } else if (common.naclModule == null) {
+ updateStatus('Creating embed: ' + tool);
+
+ // We use a non-zero sized embed to give Chrome space to place the bad
+ // plug-in graphic, if there is a problem.
+ width = typeof width !== 'undefined' ? width : 200;
+ height = typeof height !== 'undefined' ? height : 200;
+ attachDefaultListeners();
+ createNaClModule(name, tool, path, width, height, attrs);
+ } else {
+ // It's possible that the Native Client module onload event fired
+ // before the page's onload event. In this case, the status message
+ // will reflect 'SUCCESS', but won't be displayed. This call will
+ // display the current message.
+ updateStatus('Waiting.');
+ }
+}
+</pre>
+<p><code>attachDefaultListeners</code> is added before the creation of the module, to make
+sure that no messages are lost. Note that <code>window.attachListeners</code> is also
+called; this is the way that <code>common.js</code> allows each example to configure
+itself differently. If an example defines the <code>attachListeners</code> function, it
+will be called by <code>common.js</code>.</p>
+<pre class="prettyprint">
+function attachDefaultListeners() {
+ var listenerDiv = document.getElementById('listener');
+ listenerDiv.addEventListener('load', moduleDidLoad, true);
+ listenerDiv.addEventListener('message', handleMessage, true);
+ listenerDiv.addEventListener('crash', handleCrash, true);
+ if (typeof window.attachListeners !== 'undefined') {
+ window.attachListeners();
+ }
+}
+</pre>
+<p>Finally, <code>createNaClModule</code> actually creates the <code>embed</code>, and appends it as
+a child of the element with id <code>listener</code>:</p>
+<pre class="prettyprint">
+function createNaClModule(name, tool, path, width, height, attrs) {
+ var moduleEl = document.createElement('embed');
+ moduleEl.setAttribute('name', 'nacl_module');
+ moduleEl.setAttribute('id', 'nacl_module');
+ moduleEl.setAttribute('width', width);
+ moduleEl.setAttribute('height', height);
+ moduleEl.setAttribute('path', path);
+ moduleEl.setAttribute('src', path + '/' + name + '.nmf');
+
+ ...
+
+ var mimetype = mimeTypeForTool(tool);
+ moduleEl.setAttribute('type', mimetype);
+
+ var listenerDiv = document.getElementById('listener');
+ listenerDiv.appendChild(moduleEl);
+ ...
+}
+</pre>
+<p>When the module finishes loading, it will dispatch a <code>load</code> event, and the
+event listener function that was registered above (<code>moduleDidLoad</code>) will be
+called. Note that <code>common.js</code> allows each example to define a
+<code>window.moduleDidLoad</code> function, that will be called here as well.</p>
+<pre class="prettyprint">
+function moduleDidLoad() {
+ common.naclModule = document.getElementById('nacl_module');
+ updateStatus('RUNNING');
+
+ if (typeof window.moduleDidLoad !== 'undefined') {
+ window.moduleDidLoad();
+ }
+}
+</pre>
+</section></section><section id="example-specific-behavior-with-example-js">
+<h2 id="example-specific-behavior-with-example-js">Example-specific behavior with example.js</h2>
+<p>As described in the previous section, <code>common.js</code> will call certain functions
+during the module loading process. This example only needs to respond to two:
+<code>moduleDidLoad</code> and <code>handleMessage</code>.</p>
+<pre class="prettyprint">
+// This function is called by common.js when the NaCl module is
+// loaded.
+function moduleDidLoad() {
+ // Once we load, hide the plugin. In this example, we don't display anything
+ // in the plugin, so it is fine to hide it.
+ common.hideModule();
+
+ // After the NaCl module has loaded, common.naclModule is a reference to the
+ // NaCl module's &lt;embed&gt; element.
+ //
+ // postMessage sends a message to it.
+ common.naclModule.postMessage('hello');
+}
+
+// This function is called by common.js when a message is received from the
+// NaCl module.
+function handleMessage(message) {
+ var logEl = document.getElementById('log');
+ logEl.textContent += message.data;
+}
+</pre>
+</section></section>
+
+{{/partials.standard_nacl_article}}

Powered by Google App Engine
This is Rietveld 408576698