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

Side by Side Diff: native_client_sdk/src/doc/devguide/tutorial.rst

Issue 23902007: [NaCl SDK] Porting the "Getting Started" tutorial to ReST. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 .. _tutorial: 1 .. _tutorial:
2 2
3 ######################## 3 ########################
4 Getting Started Tutorial 4 C++ Tutorial: Getting Started
5 ######################## 5 ########################
eliben 2013/09/04 20:00:52 These should be the same length as the text above/
binji 2013/09/04 20:49:41 Ah, it does but I didn't notice it :) done.
6 6
7 This is the tutorial. 7 .. contents::
8 8 :local:
9 :backlinks: none
10 :depth: 1
eliben 2013/09/04 20:00:52 I think it makes sense to consistently set it to 2
binji 2013/09/04 20:49:41 That is the way the current document displays it.
11
12 Overview
13 ========
14
15 This tutorial shows you how to create, compile, and run a Native Client web
16 application. The Native Client module you will create as part of the web
17 application will be written in C++.
18
19 We recommend reading the :doc:`Native Client Technical Overview
20 <../overview>` prior to going through this tutorial.
21
22 Parts in a Native Client application
23 ------------------------------------
24
25 A Native Client web application consists of at least three parts:
eliben 2013/09/04 20:00:52 I have this in the technical overview too. Once we
binji 2013/09/04 20:49:41 Added a TODO.
26
27 * **a web page** (\*.html)
eliben 2013/09/04 20:00:52 How do you expect this to be formatted? If you wan
binji 2013/09/04 20:49:41 Done. Though it looks more "spread out" than in th
28 The web page can include HTML, JavaScript, and CSS (the JavaScript and CSS
29 can also go in separate .js and .css files).
30 * **a Native Client module** (\*.c or \*.cc before compiling; \*.nexe after
eliben 2013/09/04 20:00:52 Ah, so it's just ReST translation, no PNaCl yet?
binji 2013/09/04 20:49:41 Yes, I'll mention that in the CL description.
31 compiling)
32 Native Client modules can be written in C or C++. Modules use the Pepper API,
33 included in the SDK, as a bridge between the browser and the modules.
34 * **manifest file** (\*.nmf)
35 Browsers use an application's manifest file to determine which compiled Native
36 Client module to load based on the instruction set architecture of the user's
37 machine (e.g., x86-32, x86-64, or ARM).
38
39 What the application in this tutorial does
40 ------------------------------------------
41
42 The application in this tutorial shows how to load a Native Client module in a
43 web page, and how to send messages between JavaScript code and the C or C++
44 code in the Native Client module. In this simple application, the JavaScript
45 code in the web page sends a 'hello' message to the Native Client module. When
46 the Native Client module receives a message, it checks whether the message is
47 equal to the string 'hello'. If it is, the Native Client module returns a
48 message saying 'hello from NaCl'. A JavaScript alert panel displays the message
49 received from the Native Client module.
50
51 This tutorial also shows you how to create a set of template files that you can
52 use as a starting point for a Native Client application. The template code sets
53 up a simple message handler on the Native Client side, and includes boilerplate
54 code in the HTML file for adding an event listener to the web page to receive
55 messages from the Native Client module.
56
57 Communication between JavaScript code and Native Client modules
58 ---------------------------------------------------------------
59
60 Communication between JavaScript code in the browser and C or C++ code in a
61 Native Client module is two-way: JavaScript code can send messages to the
62 Native Client module; the C or C++ code can respond to messages from
63 JavaScript, or it can initiate its own messages to JavaScript. In all cases,
64 the communication is asynchronous: The caller (the JavaScript code in the
65 browser or the C/C++ code in the Native Client module) sends a message, but the
66 caller does not wait for, or may not even expect, a response. This behavior is
67 analogous to client/server communication on the web, where the client posts a
68 message to the server and returns immediately. The Native Client messaging
69 system is part of the Pepper API, and is described in detail in the
70 :doc:`Messaging System <coding/message-system>` chapter in the Developer's
71 Guide.
72
73 Step 1: Download and install the Native Client SDK, Python, and Xcode Developer Tools (if necessary).
eliben 2013/09/04 20:00:52 The title should probably be shorter
binji 2013/09/04 20:49:41 Done.
74 ================================================================================ =====================
75
76 Follow the instructions on the :doc:`Download <../sdk/download>` page to
77 download and install the Native Client SDK.
78
79 .. Note::
80 :class: caution
81
82 **Important:** A number of tools in the SDK require Python to run. Python is
83 typically included on Mac and Linux systems, but not on Windows systems. To
84 check whether you have Python installed on your system, enter the
85 '``python``' command on the command line; you should get the interactive
86 Python prompt (``>>>``). On Mac systems, you also need to install '``make``'
87 in order to build and run the examples in the SDK; one easy way to get
88 '``make``', along with several other useful tools, is to install Xcode
89 Developer Tools. Follow the instructions at the top of the :doc:`Download
90 <../sdk/download>` page if you need to install Python and/or Xcode
91 Developer Tools.
92
93 Step 2: Start a local server.
eliben 2013/09/04 20:00:52 Should title really end with periods?
binji 2013/09/04 20:49:41 Seems strange to me too. Done.
94 =============================
95
96 TODO(binji): This is not necessary anymore; we can use ``make run``. Some of
97 the information about why you need a webserver is still useful though...
98 Remove?
99
100 To protect against security vulnerabilities, you must load Native Client
101 modules from a web server (either remote or local). **Simply dragging and
102 dropping Native Client files into the browser address bar will not work.** For
103 more information, read about the `Same Origin Policy
104 <http://www.w3.org/Security/wiki/Same_Origin_Policy>`_, which protects the
105 user's file system from outside access.
106
107 The Native Client SDK includes a simple Python web server that you can use to
108 run applications that you build (including the application in this tutorial).
109 The server is located in the tools directory. To start the web server, go to
110 the examples directory in the SDK bundle that you are using and run the
111 ``httpd.py`` script. For example, if you are using the ``pepper_28`` bundle,
112 run the following commands::
113
114 cd pepper_28/examples
eliben 2013/09/04 20:00:52 use naclcode with :prettyprint: 0 for all these
binji 2013/09/04 20:49:41 Done.
115 python ../tools/httpd.py
116
117 If you don't specify a port number, the server defaults to port 5103, and you
118 can access the server at http://localhost:5103.
119
120 Of course, you don't have to use the server included in the SDK---any web server
121 will do. If you prefer to use another web server already installed on your
122 system, that's fine. Note also that there are ways to run Native Client
123 applications during development without a server, but these techniques require
124 you to create additional files for your application (see :doc:`Running Native
125 Client Applications <devcycle/running>` for details). For this tutorial,
126 your application must come from a server.
127
128 .. _step_3:
129
130 Step 3: Set up Google Chrome.
131 =============================
132
133 Set up the Chrome browser as follows:
134
135 a. Make sure you are using the minimum required version of Chrome.
136
137 * Your version of Chrome must be equal to or greater than the version of your
138 Pepper bundle. For example, if you're developing with the ``pepper_28``
139 bundle, you must use Google Chrome version 28 or greater. To find out what
140 version of Chrome you're using, type ``about:chrome`` or ``about:version``
141 in the Chrome address bar.
142
143 b. Enable the Native Client flag in Chrome. (Native Client is enabled by
144 default for applications distributed through the Chrome Web Store. To run
145 Native Client applications that are not distributed through the Chrome Web
146 Store, e.g., applications that you build and run locally, you must
147 specifically enable the Native Client flag in Chrome.)
148
149 * Type ``about:flags`` in the Chrome address bar and scroll down to "Native
150 Client".
151 * If the link below "Native Client" says "Disable", then Native Client is
152 already enabled and you don't need to do anything else.
153 * If the link below "Native Client" says "Enable", click the "Enable" link,
154 scroll down to the bottom of the page, and click the "Relaunch Now" button.
155 All browser windows will restart when you relaunch Chrome.
156
157 c. Disable the Chrome cache. (Chrome caches resources aggressively; you should
158 disable the cache whenever you are developing a Native Client application in
159 order to make sure Chrome loads new versions of your application.)
160
161 * Open Chrome's developer tools by clicking the menu icon |menu-icon| and
162 choosing Tools > Developer tools.
163 * Click the gear icon |gear-icon| in the bottom right corner of the Chrome
164 window.
165 * Under the "General" settings, check the box next to "Disable cache".
166
167 .. |menu-icon| image:: /images/menu-icon.png
168 .. |gear-icon| image:: /images/gear-icon.png
169
170 Step 4: Create a set of stub files for your application.
171 ========================================================
172
173 Create a set of stub files as follows:
174
175 a. Download `hello_tutorial.zip
176 <https://developers.google.com/native-client/devguide/hello_tutorial.zip>`_.
177
178 b. Unzip hello_tutorial.zip:
179
180 * On Mac/Linux, run the command "``unzip hello_tutorial.zip``" in a Terminal
181 window.
182 * On Windows, right-click on the .zip file and select "Extract All..." A
183 dialog box will open; enter a location and click "Extract".
184
185 c. Unzipping hello_tutorial.zip creates a directory called ``hello_tutorial``
186 with the following files:
187
188 * ``hello_tutorial.html``
189 * ``hello_tutorial.cc``
190 * ``hello_tutorial.nmf``
191 * ``Makefile``
192 * ``make.bat`` (for Windows)
193
194 d. Move the ``hello_tutorial`` directory so that it's under the ``examples``
195 directory where you started the local server. Its location should be, e.g.,
196 ``pepper_28/examples/hello_tutorial``.
197
198 * On Windows, depending on the location you entered when you unzipped the
199 file, there may be two ``hello_tutorial`` directories—one nested within
200 the other. Move only the inner (nested) directory to the ``examples``
201 directory.
202
203 .. Note::
204 :class: note
205
206 **Note regarding the location of project directories:**
207
208 * In this tutorial, you are adding the ``hello_tutorial`` directory under the
209 ``examples`` directory because the ``examples`` directory is where your
210 local server is running, ready to serve your tutorial application. You can
211 place your project directory anywhere on your file system, as long as that
212 location is being served by your server.
213 * If you do place the ``hello_tutorial`` project directory in another
214 location, you must set the `environment variable
215 <http://en.wikipedia.org/wiki/Environment_variable>`_ ``NACL_SDK_ROOT`` to
216 point to the top-level directory of the bundle you are using (e.g.,
217 ``<location-where-you-installed-the-SDK>/pepper_28``) in order for the
218 Makefile that's included in the project directory to work.
219 * If you use the location recommended above
220 (``pepper_28/examples/hello_tutorial``), be careful when you update the
221 SDK. The command '``naclsdk update pepper_28 --force``' will overwrite the
222 ``pepper_28`` directory, so move any project directories you want to keep
223 to another location.
224
225 Step 5: Compile the Native Client module and run the stub application.
226 ======================================================================
227
228 The files you downloaded in the previous step constitute a stub application
229 that simply loads a Native Client module into a web page and updates a
230 ``<div>`` element on the page with the status of the module load.
231
232 To compile the Native Client module ``hello_tutorial.cc,`` run '``make``'::
233
234 cd pepper_28/examples/hello_tutorial
235 make
236
237 The '``make``' command runs the necessary compile and link commands to produce
238 three executable Native Client modules (for the x86-32, x86-64, and ARM
239 architectures). The executable files are named as follows:
240
241 * ``hello_tutorial_x86_32.nexe``
242 * ``hello_tutorial_x86_64.nexe``
243 * ``hello_tutorial_arm.nexe``
244
245 Assuming you are using the local server and the project directory specified
246 above, you can load the ``hello_tutorial.html`` web page into Chrome by visiting
247 the following URL: http://localhost:5103/hello_tutorial/hello_tutorial.html. If
248 Chrome loads the Native Client module successfully, the Status display on the
249 page should change from "LOADING..." to "SUCCESS".
250
251 Step 6: Review the code in the stub application.
252 ================================================
253
254 The section highlights some of the code in the stub application.
255
256 Makefile
257 ``Makefile`` contains the compile and link commands to build the executable
258 Native Client modules (.nexe files) for your application. The Native Client
259 SDK includes multiple GCC‑based toolchains to build modules for multiple
260 architectures (x86 and ARM) using different implementations of the C library
261 (`newlib <http://www.sourceware.org/newlib/>`_ and `glibc
262 <http://www.gnu.org/software/libc/>`_). The commands in the tutorial
263 ``Makefile`` build the application using the newlib C library for the x86 and
264 ARM architectures. The commands use the toolchains located in the
265 ``pepper_28/toolchain/<platform>_x86_newlib`` and ``<platform>_arm_newlib``
266 directories. For information about how to use Makefiles and the '``make``'
267 command, see the `GNU 'make' manual
268 <http://www.gnu.org/software/make/manual/make.html>`_.
269
270 hello_tutorial.nmf
271 ``hello_tutorial.nmf`` is a Native Client manifest file that tells Chrome
272 which compiled Native Client module (.nexe) to load based on the instruction
273 set architecture of the user's machine (e.g., x86-32, x86-64, or ARM). For
274 applications compiled using glibc, manifest files must also specify the
275 shared libraries that the applications use.
276
277 hello_tutorial.html
278 ``hello_tutorial.html`` is the web page that corresponds to your application.
279 The page includes an ``<embed>`` element that loads the compiled Native
280 Client module::
281
282 <div id="listener">
283 <script type="text/javascript">
284 var listener = document.getElementById('listener');
285 listener.addEventListener('load', moduleDidLoad, true);
286 listener.addEventListener('message', handleMessage, true);
287 </script>
288
289 <embed name="nacl_module"
290 id="hello_tutorial"
291 width=0 height=0
292 src="hello_tutorial.nmf"
293 type="application/x-nacl" />
294 </div>
295
296 The ``src`` attribute in the ``<embed>`` element points to the Native Client
297 manifest file, which tells the browser which .nexe file to load based on the
298 instruction set architecture of the user's machine. The ``width`` and
299 ``height`` attributes in the ``<embed>`` element are set to 0 because the
300 Native Client module in this example does not have any graphical component.
301 The ``type`` attribute declares the MIME type to be ``x-nacl``, i.e., an
302 executable Native Client module.
303
304 The ``<embed>`` element is wrapped inside a ``<div>`` element that has two
305 event listeners attached—one for the 'load' event, which fires when the
306 browser successfully loads the Native Client module, and one for the
307 'message' event, which fires when the Native Client module uses the
308 ``PostMessage()`` method (in the `pp::Instance
309 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance>`_
310 class) to send a message to the JavaScript code in the application. This
311 technique of attaching the event listeners to a parent ``<div>`` element
312 (rather than directly to the ``<embed>`` element) is used to ensure that the
313 event listeners are active before the module 'load' event fires.
314
315 The simple event handlers in this tutorial are implemented in the
316 ``moduleDidLoad()`` and ``handleMessage()`` JavaScript functions.
317 ``moduleDidLoad()`` changes the text inside the 'status_field' ``<div>``
318 element. handleMessage() displays the content of messages sent from the
319 Native Client module in a browser alert panel. For a description of 'load',
320 'message', and other Native Client events, see the :doc:`Progress Events
321 <coding/progress-events>` chapter of the Developer's Guide.
322
323 hello_tutorial.cc
324 Native Client includes the concept of modules and instances:
325
326 * A **module** is C or C++ code compiled into an executable .nexe file.
327 * An **instance** is a rectangle on a web page that is managed by a module.
328 The rectangle can have dimensions 0x0, in which case the instance does not
329 have a visual component on the web page. An instance is created by
330 including an ``<embed>`` element in a web page. A module may be included in
331 a web page multiple times by using multiple ``<embed>`` elements that refer
332 to the module; in this case the Native Client runtime system loads the
333 module once and creates multiple instances that are managed by the module.
334
335 The example in this tutorial includes one module
336 (``hello_tutorial_x86_32.nexe``, ``hello_tutorial_x86_64.nexe``, or
337 ``hello_tutorial_arm.nexe``, depending on the instruction set architecture of
338 the user's machine), and one instance (one ``<embed>`` element that loads the
339 module). The source code for the module is in the file ``hello_tutorial.cc``.
340 This source code contains the minimum code required in a C++ Native Client
341 module—an implementation of the `Instance
342 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance>`_
343 and `Module
344 <https://developers.google.com/native-client/peppercpp/classpp_1_1_module>`_
345 classes. These implementations don't actually do anything yet.
346
347 Step 7: Modify the web page to send a message to the Native Client module.
348 ==========================================================================
349
350 In this step, you'll modify the web page (``hello_tutorial.html``) to send a
351 message to the Native Client module after the page loads the module.
352
353 Look for the JavaScript function ``moduleDidLoad()``, and add the new code below
354 (indicated by boldface type) to send a 'hello' message to the Native Client
355 module::
356
357 function moduleDidLoad() {
eliben 2013/09/04 20:00:52 .. naclcode::
binji 2013/09/04 20:49:41 Done.
358 HelloTutorialModule = document.getElementById('hello_tutorial');
359 updateStatus('SUCCESS');
360 // Send a message to the NaCl module.
361 HelloTutorialModule.postMessage('hello');
362 }
363
364 Step 8: Implement a message handler in the Native Client module.
365 ================================================================
366
367 In this step, you'll modify the Native Client module (``hello_tutorial.cc``) to
368 respond to the message received from the JavaScript code in the application.
369 Specifically, you'll:
370
371 * implement the ``HandleMessage()`` function for the module, and
372 * use the ``PostMessage()`` function to send a message from the module to the
373 JavaScript code
374
375 First, add code to define the variables used by the Native Client module (the
376 'hello' string you're expecting to receive from JavaScript and the reply string
377 you want to return to JavaScript as a response). In the file
378 ``hello_tutorial.cc``, add this code after the ``#include`` statements::
379
380 namespace {
381 // The expected string sent by the browser.
382 const char* const kHelloString = "hello";
383 // The string sent back to the browser upon receipt of a message
384 // containing "hello".
385 const char* const kReplyString = "hello from NaCl";
386 } // namespace
387
388 Now, implement the ``HandleMessage()`` method to check for ``kHelloString`` and
389 return ``kReplyString.`` Look for the following line::
390
391 // TODO(sdk_user): 1. Make this function handle the incoming message.
392
393 Replace the above line with the boldface code below::
394
395 virtual void HandleMessage(const pp::Var& var_message) {
396 if (!var_message.is_string())
397 return;
398 std::string message = var_message.AsString();
399 pp::Var var_reply;
400 if (message == kHelloString) {
401 var_reply = pp::Var(kReplyString);
402 PostMessage(var_reply);
403 }
404 }
405
406 See the Pepper API documentation for additional information about the
407 `pp::Instance.HandleMessage
408 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a5dce8c8b36b1df7cfcc12e42397a35e8>`_
409 and `pp::Instance.PostMessage
410 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html #a67e888a4e4e23effe7a09625e73ecae9>`_
411 methods.
412
413 Step 9: Compile the Native Client module and run the application again.
414 =======================================================================
415
416 Compile the Native Client module by running the '``make``' command again.
417
418 Run the application by reloading hello_tutorial.html in Chrome. (The page
419 should be at http://localhost:5103/hello_tutorial/hello_tutorial.html assuming
420 the setup described above.)
421
422 After Chrome loads the Native Client module, you should see an alert panel
423 appear with the message sent from the module.
424
425 Troubleshooting
426 ===============
427
428 If your application doesn't run, see :ref:`Step 3 <step_3>` above
429 to verify that you've set up your environment correctly, including both the
430 Chrome browser and the local server. Make sure that you're running a version of
431 Chrome that is equal to or greater than the SDK bundle version you are using,
432 that you've enabled the Native Client flag and relaunched Chrome, that you've
433 disabled the Chrome cache, and that **you're accessing your application from a
434 local web server (rather than by dragging the HTML file into your browser)**.
435
436 For additional troubleshooting information, check the `FAQ
437 <https://developers.google.com/native-client/faq.html#HangOnLoad>`_.
438
439 Next steps
440 ==========
441
442 * See the :doc:`Application Structure <coding/application-structure>`
443 chapter in the Developer's Guide for information about how to structure a
444 Native Client module.
445 * Check the `C++ Reference
446 <https://developers.google.com/native-client/peppercpp>`_ for details about
447 how to use the Pepper APIs.
448 * Browse through the source code of the SDK examples (in the ``examples``
449 directory) to learn additional techniques for writing Native Client
450 applications and using the Pepper APIs.
451 * See the :doc:`Building <devcycle/building>`, :doc:`Running
452 <devcycle/running>`, and :doc:`Debugging pages <devcycle/debugging>`
453 for information about how to build, run, and debug Native Client
454 applications.
455 * Check the `naclports <http://code.google.com/p/naclports/>`_ project to see
456 what libraries have been ported for use with Native Client. If you port an
457 open-source library for your own use, we recommend adding it to naclports
458 (see `How to check code into naclports
459 <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_).
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698