- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / doc / devguide / tutorial / tutorial-part1.rst
1 .. _tutorial:
2
3 ######################################
4 C++ Tutorial: Getting Started (Part 1)
5 ######################################
6
7 .. contents::
8   :local:
9   :backlinks: none
10   :depth: 2
11
12 Overview
13 ========
14
15 This tutorial shows how to build and run a web application using Portable Native
16 Client (PNaCl). This is a client-side application that uses HTML, JavaScript and
17 a Native Client module written in C++. The PNaCl toolchain is used to enable
18 running the Native Client module directly from a web page.
19
20 It's recommended to read the :doc:`Native Client Technical Overview
21 </overview>` prior to going through this tutorial.
22
23 What the application in this tutorial does
24 ------------------------------------------
25
26 The application in this tutorial shows how to load a Native Client module in a
27 web page, and how to send messages between JavaScript and the C++ code in the
28 Native Client module. In this simple application, the JavaScript code in the web
29 page sends a ``'hello'`` message to the Native Client module. When the Native
30 Client module receives a message, it checks whether the message is equal to the
31 string ``'hello'``. If it is, the Native Client module returns a message saying
32 ``'hello from NaCl'``. A JavaScript alert panel displays the message received
33 from the Native Client module.
34
35 Communication between JavaScript and Native Client modules
36 ----------------------------------------------------------
37
38 The Native Client programming model supports bidirectional communication between
39 JavaScript and the Native Client module (C/C++ code). Both sides can initiate
40 and respond to messages. In all cases, the communication is asynchronous: The
41 caller (JavaScript or the Native Client module) sends a message, but the caller
42 does not wait for, or may not even expect, a response. This behavior is
43 analogous to client/server communication on the web, where the client posts a
44 message to the server and returns immediately. The Native Client messaging
45 system is part of the Pepper API, and is described in detail in
46 :doc:`Developer's Guide: Messaging System </devguide/coding/message-system>`.
47 It is also similar to the way `web workers
48 <http://en.wikipedia.org/wiki/Web_worker>`_ interact with the main document in
49 JavaScript.
50
51 Step 1: Download and install the Native Client SDK
52 ==================================================
53
54 Follow the instructions on the :doc:`Download </sdk/download>` page to
55 download and install the Native Client SDK.
56
57 .. _tutorial_step_2:
58
59 Step 2: Start a local server
60 ============================
61
62 To simulate a production environment, the SDK provides a simple web server that
63 can be used to serve the application on ``localhost``. A convenience Makefile
64 rule called ``serve`` is the easiest way to invoke it:
65
66 .. naclcode::
67   :prettyprint: 0
68
69   $ cd pepper_$(VERSION)/getting_started
70   $ make serve
71
72 .. Note::
73   :class: note
74
75   The SDK may consist of several "bundles", one per Chrome/Pepper version (see
76   :doc:`versioning information </version>`). In the sample invocation above
77   ``pepper_$(VERSION)`` refers to the specific version you want to use. For
78   example, ``pepper_31``. If you don't know which version you need, use the
79   one labeled ``(stable)`` by ``naclsdk list``. See :doc:`Download the Native
80   Client SDK </sdk/download>` for more details.
81
82 If no port number is specified, the server defaults to port 5103, and can be
83 accessed at http://localhost:5103.
84
85 Any server can be used for the purpose of development. The one provided with the
86 SDK is just a convenience, not a requirement.
87
88 .. _tutorial_step_3:
89
90 Step 3: Set up the Chrome browser
91 =================================
92
93 PNaCl is enabled by default in Chrome version 31 and later. Please make sure
94 that you have a suitable version to work through this tutorial. It's also
95 important to use a Chrome version that's the same or newer than the SDK bundle
96 used to build the Native Client modules.
97
98 .. Note::
99   :class: note
100
101   To find out the version of Chrome, type ``about:chrome`` in the address bar.
102
103 For a better development experience, it's also recommended to disable the
104 Chrome cache. Chrome caches resources aggressively; disabling the cache helps
105 make sure that the latest version of the Native Client module is loaded during
106 development.
107
108 * Open Chrome's developer tools by clicking the menu icon |menu-icon| and
109   choosing ``Tools > Developer tools``.
110 * Click the gear icon |gear-icon| in the bottom right corner of the Chrome
111   window.
112 * Under the "General" settings, check the box next to "Disable cache (while
113   DevTools is open)".
114 * Keep the Developer Tools pane open while developing Native Client
115   applications.
116
117 .. |menu-icon| image:: /images/menu-icon.png
118 .. |gear-icon| image:: /images/gear-icon.png
119
120 Step 4: Stub code for the tutorial
121 ==================================
122
123 The stub code for the tutorial is avalable in the SDK, in
124 ``pepper_$(VERSION)/getting_started/part1``. It contains the following files:
125
126 * ``index.html``: Contains the HTML layout of the page as well as the JavaScript
127   code that interacts with the Native Client module.
128
129   The Native Client module is included in the page with an ``<embed>`` tag that
130   points to a manifest file.
131 * ``hello_tutorial.nmf``: A manifest file that's used to point the HTML to the
132   Native Client module and optionally provide additional commands to the PNaCl
133   translator that is part of the Chrome browser.
134 * ``hello_tutorial.cc``: C++ code for a simple Native Client module.
135 * ``Makefile``: Compilation commands to build the **pexe** (portable executable)
136   from the C++ code in ``hello_tutorial.cc``.
137
138 It's a good idea to take a look at these files now---they contain a large amount
139 of comments that help explain their structure and contents. For more details
140 on the structure of a typical Native Client application, see
141 :doc:`Application Structure </devguide/coding/application-structure>`.
142
143 The stub code is intentionally very minimal. The C++ code does not do anything
144 except correctly initialize itself. The JavaScript code waits for the Native
145 Client module to load and changes the status text on the web page accordingly.
146
147 .. _tutorial_step_5:
148
149 Step 5: Compile the Native Client module and run the stub application
150 =====================================================================
151
152 To compile the Native Client module, run ``make``:
153
154 .. naclcode::
155   :prettyprint: 0
156
157   $ cd pepper_$(VERSION)/getting_started/part1
158   $ make
159
160 Since the sample is located within the SDK tree, the Makefile knows how to find
161 the PNaCl toolchain automatically and use it to build the module. If you're
162 building applications outside the NaCl SDK tree, you should set the
163 ``$NACL_SDK_ROOT`` environment variable. See :doc:`Building Native Client
164 Modules </devguide//devcycle/building>` for more details.
165
166 Assuming the local server was started according to the instructions in
167 :ref:`Step 2 <tutorial_step_2>`, you can now load the sample by pointing Chrome
168 to http://localhost:5103/part1. Chrome should load the Native Client module
169 successfully and the Status text should change from "LOADING..." to "SUCCESS".
170 If you run into problems, check out the :ref:`Troubleshooting section
171 <tutorial_troubleshooting>` below.
172
173 Step 6: Modify the JavaScript code to send a message to the Native Client module
174 ================================================================================
175
176 In this step, you'll modify the web page (``index.html``) to send a message to
177 the Native Client module after the page loads the module.
178
179 Look for the JavaScript function ``moduleDidLoad()``, and add new code to send
180 a 'hello' message to the module. The new function should look as follows:
181
182 .. naclcode::
183
184     function moduleDidLoad() {
185       HelloTutorialModule = document.getElementById('hello_tutorial');
186       updateStatus('SUCCESS');
187       // Send a message to the Native Client module
188       HelloTutorialModule.postMessage('hello');
189     }
190
191 Step 7: Implement a message handler in the Native Client module
192 ===============================================================
193
194 In this step, you'll modify the Native Client module (``hello_tutorial.cc``) to
195 respond to the message received from the JavaScript code in the application.
196 Specifically, you'll:
197
198 * Implement the ``HandleMessage()`` member function of the module instance.
199 * Use the ``PostMessage()`` member function to send a message from the module to
200   the JavaScript code.
201
202 First, add code to define the variables used by the Native Client module (the
203 'hello' string you're expecting to receive from JavaScript and the reply string
204 you want to return to JavaScript as a response). In the file
205 ``hello_tutorial.cc``, add this code after the ``#include`` statements:
206
207 .. naclcode::
208
209   namespace {
210   // The expected string sent by the browser.
211   const char* const kHelloString = "hello";
212   // The string sent back to the browser upon receipt of a message
213   // containing "hello".
214   const char* const kReplyString = "hello from NaCl";
215   } // namespace
216
217 Now, implement the ``HandleMessage()`` member function to check for
218 ``kHelloString`` and return ``kReplyString.`` Look for the following line:
219
220 .. naclcode::
221
222     // TODO(sdk_user): 1. Make this function handle the incoming message.
223
224 Populate the member function with code, as follows:
225
226 .. naclcode::
227
228   virtual void HandleMessage(const pp::Var& var_message) {
229     if (!var_message.is_string())
230       return;
231     std::string message = var_message.AsString();
232     pp::Var var_reply;
233     if (message == kHelloString) {
234       var_reply = pp::Var(kReplyString);
235       PostMessage(var_reply);
236     }
237   }
238
239 See the Pepper API documentation for additional information about the
240 `pp::Instance.HandleMessage
241 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html#a5dce8c8b36b1df7cfcc12e42397a35e8>`_
242 and `pp::Instance.PostMessage
243 <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html#a67e888a4e4e23effe7a09625e73ecae9>`_
244 member functions.
245
246 Step 8: Compile the Native Client module and run the application again
247 ======================================================================
248
249 Compile the Native Client module by running the ``make`` command again.
250
251 Re-run the application by reloading http://localhost:5103/part1 in Chrome.
252
253 After Chrome loads the Native Client module, you should see an alert panel
254 appear with the message sent from the module.
255
256 .. _tutorial_troubleshooting:
257
258 Troubleshooting
259 ===============
260
261 If your application doesn't run, see :ref:`Step 3 <tutorial_step_3>` above to
262 verify that you've set up your environment correctly, including both the Chrome
263 browser and the local server. Make sure that you're running a correct version of
264 Chrome, which is also greater or equal than the SDK bundle version you are
265 using.
266
267 Another useful debugging aid is the Chrome JavaScript console (available via the
268 ``Tools`` menu in Chrome). Examine it for clues about what went wrong. For
269 example, if there's a message saying "NaCl module crashed", there is a
270 possibility that the Native Client module has a bug; :doc:`debugging
271 </devguide/devcycle/debugging>` may be required.
272
273 There's more information about troubleshooting in the documentation:
274
275 * :ref:`FAQ Troubleshooting <faq_troubleshooting>`.
276 * The :doc:`Progress Events </devguide/coding/progress-events>` document
277   contains some useful information about handling error events.
278
279 Next steps
280 ==========
281
282 * See the :doc:`Application Structure </devguide/coding/application-structure>`
283   chapter in the Developer's Guide for information about how to structure a
284   Native Client module.
285 * Check the `C++ Reference
286   <https://developers.google.com/native-client/peppercpp>`_ for details about
287   how to use the Pepper APIs.
288 * Browse through the source code of the SDK examples (in the ``examples``
289   directory) to learn additional techniques for writing Native Client
290   applications and using the Pepper APIs.
291 * See the :doc:`Building </devguide/devcycle/building>`, :doc:`Running
292   </devguide/devcycle/running>`, and :doc:`Debugging pages
293   </devguide/devcycle/debugging>` for information about how to build, run, and
294   debug Native Client applications.
295 * Check the `naclports <http://code.google.com/p/naclports/>`_ project to see
296   what libraries have been ported for use with Native Client. If you port an
297   open-source library for your own use, we recommend adding it to naclports
298   (see `How to check code into naclports
299   <http://code.google.com/p/naclports/wiki/HowTo_Checkin>`_).