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

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

Powered by Google App Engine
This is Rietveld 408576698