diff options
Diffstat (limited to 'bitbake/doc/bitbake-user-manual/bitbake-user-manual-hello.rst')
-rw-r--r-- | bitbake/doc/bitbake-user-manual/bitbake-user-manual-hello.rst | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/bitbake/doc/bitbake-user-manual/bitbake-user-manual-hello.rst b/bitbake/doc/bitbake-user-manual/bitbake-user-manual-hello.rst new file mode 100644 index 0000000000..e3fd321588 --- /dev/null +++ b/bitbake/doc/bitbake-user-manual/bitbake-user-manual-hello.rst | |||
@@ -0,0 +1,415 @@ | |||
1 | .. SPDX-License-Identifier: CC-BY-2.5 | ||
2 | |||
3 | =================== | ||
4 | Hello World Example | ||
5 | =================== | ||
6 | |||
7 | BitBake Hello World | ||
8 | =================== | ||
9 | |||
10 | The simplest example commonly used to demonstrate any new programming | ||
11 | language or tool is the "`Hello | ||
12 | World <http://en.wikipedia.org/wiki/Hello_world_program>`__" example. | ||
13 | This appendix demonstrates, in tutorial form, Hello World within the | ||
14 | context of BitBake. The tutorial describes how to create a new project | ||
15 | and the applicable metadata files necessary to allow BitBake to build | ||
16 | it. | ||
17 | |||
18 | Obtaining BitBake | ||
19 | ================= | ||
20 | |||
21 | See the :ref:`bitbake-user-manual/bitbake-user-manual-hello:obtaining bitbake` section for | ||
22 | information on how to obtain BitBake. Once you have the source code on | ||
23 | your machine, the BitBake directory appears as follows: :: | ||
24 | |||
25 | $ ls -al | ||
26 | total 100 | ||
27 | drwxrwxr-x. 9 wmat wmat 4096 Jan 31 13:44 . | ||
28 | drwxrwxr-x. 3 wmat wmat 4096 Feb 4 10:45 .. | ||
29 | -rw-rw-r--. 1 wmat wmat 365 Nov 26 04:55 AUTHORS | ||
30 | drwxrwxr-x. 2 wmat wmat 4096 Nov 26 04:55 bin | ||
31 | drwxrwxr-x. 4 wmat wmat 4096 Jan 31 13:44 build | ||
32 | -rw-rw-r--. 1 wmat wmat 16501 Nov 26 04:55 ChangeLog | ||
33 | drwxrwxr-x. 2 wmat wmat 4096 Nov 26 04:55 classes | ||
34 | drwxrwxr-x. 2 wmat wmat 4096 Nov 26 04:55 conf | ||
35 | drwxrwxr-x. 3 wmat wmat 4096 Nov 26 04:55 contrib | ||
36 | -rw-rw-r--. 1 wmat wmat 17987 Nov 26 04:55 COPYING | ||
37 | drwxrwxr-x. 3 wmat wmat 4096 Nov 26 04:55 doc | ||
38 | -rw-rw-r--. 1 wmat wmat 69 Nov 26 04:55 .gitignore | ||
39 | -rw-rw-r--. 1 wmat wmat 849 Nov 26 04:55 HEADER | ||
40 | drwxrwxr-x. 5 wmat wmat 4096 Jan 31 13:44 lib | ||
41 | -rw-rw-r--. 1 wmat wmat 195 Nov 26 04:55 MANIFEST.in | ||
42 | -rw-rw-r--. 1 wmat wmat 2887 Nov 26 04:55 TODO | ||
43 | |||
44 | At this point, you should have BitBake cloned to a directory that | ||
45 | matches the previous listing except for dates and user names. | ||
46 | |||
47 | Setting Up the BitBake Environment | ||
48 | ================================== | ||
49 | |||
50 | First, you need to be sure that you can run BitBake. Set your working | ||
51 | directory to where your local BitBake files are and run the following | ||
52 | command: :: | ||
53 | |||
54 | $ ./bin/bitbake --version | ||
55 | BitBake Build Tool Core version 1.23.0, bitbake version 1.23.0 | ||
56 | |||
57 | The console output tells you what version | ||
58 | you are running. | ||
59 | |||
60 | The recommended method to run BitBake is from a directory of your | ||
61 | choice. To be able to run BitBake from any directory, you need to add | ||
62 | the executable binary to your binary to your shell's environment | ||
63 | ``PATH`` variable. First, look at your current ``PATH`` variable by | ||
64 | entering the following: :: | ||
65 | |||
66 | $ echo $PATH | ||
67 | |||
68 | Next, add the directory location | ||
69 | for the BitBake binary to the ``PATH``. Here is an example that adds the | ||
70 | ``/home/scott-lenovo/bitbake/bin`` directory to the front of the | ||
71 | ``PATH`` variable: :: | ||
72 | |||
73 | $ export PATH=/home/scott-lenovo/bitbake/bin:$PATH | ||
74 | |||
75 | You should now be able to enter the ``bitbake`` command from the command | ||
76 | line while working from any directory. | ||
77 | |||
78 | The Hello World Example | ||
79 | ======================= | ||
80 | |||
81 | The overall goal of this exercise is to build a complete "Hello World" | ||
82 | example utilizing task and layer concepts. Because this is how modern | ||
83 | projects such as OpenEmbedded and the Yocto Project utilize BitBake, the | ||
84 | example provides an excellent starting point for understanding BitBake. | ||
85 | |||
86 | To help you understand how to use BitBake to build targets, the example | ||
87 | starts with nothing but the ``bitbake`` command, which causes BitBake to | ||
88 | fail and report problems. The example progresses by adding pieces to the | ||
89 | build to eventually conclude with a working, minimal "Hello World" | ||
90 | example. | ||
91 | |||
92 | While every attempt is made to explain what is happening during the | ||
93 | example, the descriptions cannot cover everything. You can find further | ||
94 | information throughout this manual. Also, you can actively participate | ||
95 | in the :oe_lists:`/g/bitbake-devel` | ||
96 | discussion mailing list about the BitBake build tool. | ||
97 | |||
98 | .. note:: | ||
99 | |||
100 | This example was inspired by and drew heavily from | ||
101 | `Mailing List post - The BitBake equivalent of "Hello, World!" | ||
102 | <http://www.mail-archive.com/yocto@yoctoproject.org/msg09379.html>`_. | ||
103 | |||
104 | As stated earlier, the goal of this example is to eventually compile | ||
105 | "Hello World". However, it is unknown what BitBake needs and what you | ||
106 | have to provide in order to achieve that goal. Recall that BitBake | ||
107 | utilizes three types of metadata files: | ||
108 | :ref:`bitbake-user-manual/bitbake-user-manual-intro:configuration files`, | ||
109 | :ref:`bitbake-user-manual/bitbake-user-manual-intro:classes`, and | ||
110 | :ref:`bitbake-user-manual/bitbake-user-manual-intro:recipes`. | ||
111 | But where do they go? How does BitBake find | ||
112 | them? BitBake's error messaging helps you answer these types of | ||
113 | questions and helps you better understand exactly what is going on. | ||
114 | |||
115 | Following is the complete "Hello World" example. | ||
116 | |||
117 | #. **Create a Project Directory:** First, set up a directory for the | ||
118 | "Hello World" project. Here is how you can do so in your home | ||
119 | directory: :: | ||
120 | |||
121 | $ mkdir ~/hello | ||
122 | $ cd ~/hello | ||
123 | |||
124 | This is the directory that | ||
125 | BitBake will use to do all of its work. You can use this directory | ||
126 | to keep all the metafiles needed by BitBake. Having a project | ||
127 | directory is a good way to isolate your project. | ||
128 | |||
129 | #. **Run BitBake:** At this point, you have nothing but a project | ||
130 | directory. Run the ``bitbake`` command and see what it does: :: | ||
131 | |||
132 | $ bitbake | ||
133 | The BBPATH variable is not set and bitbake did not | ||
134 | find a conf/bblayers.conf file in the expected location. | ||
135 | Maybe you accidentally invoked bitbake from the wrong directory? | ||
136 | DEBUG: Removed the following variables from the environment: | ||
137 | GNOME_DESKTOP_SESSION_ID, XDG_CURRENT_DESKTOP, | ||
138 | GNOME_KEYRING_CONTROL, DISPLAY, SSH_AGENT_PID, LANG, no_proxy, | ||
139 | XDG_SESSION_PATH, XAUTHORITY, SESSION_MANAGER, SHLVL, | ||
140 | MANDATORY_PATH, COMPIZ_CONFIG_PROFILE, WINDOWID, EDITOR, | ||
141 | GPG_AGENT_INFO, SSH_AUTH_SOCK, GDMSESSION, GNOME_KEYRING_PID, | ||
142 | XDG_SEAT_PATH, XDG_CONFIG_DIRS, LESSOPEN, DBUS_SESSION_BUS_ADDRESS, | ||
143 | _, XDG_SESSION_COOKIE, DESKTOP_SESSION, LESSCLOSE, DEFAULTS_PATH, | ||
144 | UBUNTU_MENUPROXY, OLDPWD, XDG_DATA_DIRS, COLORTERM, LS_COLORS | ||
145 | |||
146 | The majority of this output is specific to environment variables that | ||
147 | are not directly relevant to BitBake. However, the very first | ||
148 | message regarding the ``BBPATH`` variable and the | ||
149 | ``conf/bblayers.conf`` file is relevant. | ||
150 | |||
151 | When you run BitBake, it begins looking for metadata files. The | ||
152 | :term:`BBPATH` variable is what tells BitBake where | ||
153 | to look for those files. ``BBPATH`` is not set and you need to set | ||
154 | it. Without ``BBPATH``, BitBake cannot find any configuration files | ||
155 | (``.conf``) or recipe files (``.bb``) at all. BitBake also cannot | ||
156 | find the ``bitbake.conf`` file. | ||
157 | |||
158 | #. **Setting BBPATH:** For this example, you can set ``BBPATH`` in | ||
159 | the same manner that you set ``PATH`` earlier in the appendix. You | ||
160 | should realize, though, that it is much more flexible to set the | ||
161 | ``BBPATH`` variable up in a configuration file for each project. | ||
162 | |||
163 | From your shell, enter the following commands to set and export the | ||
164 | ``BBPATH`` variable: :: | ||
165 | |||
166 | $ BBPATH="projectdirectory" | ||
167 | $ export BBPATH | ||
168 | |||
169 | Use your actual project directory in the command. BitBake uses that | ||
170 | directory to find the metadata it needs for your project. | ||
171 | |||
172 | .. note:: | ||
173 | |||
174 | When specifying your project directory, do not use the tilde | ||
175 | ("~") character as BitBake does not expand that character as the | ||
176 | shell would. | ||
177 | |||
178 | #. **Run BitBake:** Now that you have ``BBPATH`` defined, run the | ||
179 | ``bitbake`` command again: :: | ||
180 | |||
181 | $ bitbake | ||
182 | ERROR: Traceback (most recent call last): | ||
183 | File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped | ||
184 | return func(fn, *args) | ||
185 | File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 173, in parse_config_file | ||
186 | return bb.parse.handle(fn, data, include) | ||
187 | File "/home/scott-lenovo/bitbake/lib/bb/parse/__init__.py", line 99, in handle | ||
188 | return h['handle'](fn, data, include) | ||
189 | File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 120, in handle | ||
190 | abs_fn = resolve_file(fn, data) | ||
191 | File "/home/scott-lenovo/bitbake/lib/bb/parse/__init__.py", line 117, in resolve_file | ||
192 | raise IOError("file %s not found in %s" % (fn, bbpath)) | ||
193 | IOError: file conf/bitbake.conf not found in /home/scott-lenovo/hello | ||
194 | |||
195 | ERROR: Unable to parse conf/bitbake.conf: file conf/bitbake.conf not found in /home/scott-lenovo/hello | ||
196 | |||
197 | This sample output shows that BitBake could not find the | ||
198 | ``conf/bitbake.conf`` file in the project directory. This file is | ||
199 | the first thing BitBake must find in order to build a target. And, | ||
200 | since the project directory for this example is empty, you need to | ||
201 | provide a ``conf/bitbake.conf`` file. | ||
202 | |||
203 | #. **Creating conf/bitbake.conf:** The ``conf/bitbake.conf`` includes | ||
204 | a number of configuration variables BitBake uses for metadata and | ||
205 | recipe files. For this example, you need to create the file in your | ||
206 | project directory and define some key BitBake variables. For more | ||
207 | information on the ``bitbake.conf`` file, see | ||
208 | http://git.openembedded.org/bitbake/tree/conf/bitbake.conf. | ||
209 | |||
210 | Use the following commands to create the ``conf`` directory in the | ||
211 | project directory: :: | ||
212 | |||
213 | $ mkdir conf | ||
214 | |||
215 | From within the ``conf`` directory, | ||
216 | use some editor to create the ``bitbake.conf`` so that it contains | ||
217 | the following: :: | ||
218 | |||
219 | PN = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}" | ||
220 | |||
221 | TMPDIR = "${TOPDIR}/tmp" | ||
222 | CACHE = "${TMPDIR}/cache" | ||
223 | STAMP = "${TMPDIR}/${PN}/stamps" | ||
224 | T = "${TMPDIR}/${PN}/work" | ||
225 | B = "${TMPDIR}/${PN}" | ||
226 | |||
227 | .. note:: | ||
228 | |||
229 | Without a value for PN , the variables STAMP , T , and B , prevent more | ||
230 | than one recipe from working. You can fix this by either setting PN to | ||
231 | have a value similar to what OpenEmbedded and BitBake use in the default | ||
232 | bitbake.conf file (see previous example). Or, by manually updating each | ||
233 | recipe to set PN . You will also need to include PN as part of the STAMP | ||
234 | , T , and B variable definitions in the local.conf file. | ||
235 | |||
236 | The ``TMPDIR`` variable establishes a directory that BitBake uses | ||
237 | for build output and intermediate files other than the cached | ||
238 | information used by the | ||
239 | :ref:`bitbake-user-manual/bitbake-user-manual-execution:setscene` | ||
240 | process. Here, the ``TMPDIR`` directory is set to ``hello/tmp``. | ||
241 | |||
242 | .. tip:: | ||
243 | |||
244 | You can always safely delete the tmp directory in order to rebuild a | ||
245 | BitBake target. The build process creates the directory for you when you | ||
246 | run BitBake. | ||
247 | |||
248 | For information about each of the other variables defined in this | ||
249 | example, check :term:`PN`, :term:`TOPDIR`, :term:`CACHE`, :term:`STAMP`, | ||
250 | :term:`T` or :term:`B` to take you to the definitions in the | ||
251 | glossary. | ||
252 | |||
253 | #. **Run BitBake:** After making sure that the ``conf/bitbake.conf`` file | ||
254 | exists, you can run the ``bitbake`` command again: :: | ||
255 | |||
256 | $ bitbake | ||
257 | ERROR: Traceback (most recent call last): | ||
258 | File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped | ||
259 | return func(fn, *args) | ||
260 | File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 177, in _inherit | ||
261 | bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data) | ||
262 | File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/BBHandler.py", line 92, in inherit | ||
263 | include(fn, file, lineno, d, "inherit") | ||
264 | File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 100, in include | ||
265 | raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno) | ||
266 | ParseError: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass | ||
267 | |||
268 | ERROR: Unable to parse base: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass | ||
269 | |||
270 | In the sample output, | ||
271 | BitBake could not find the ``classes/base.bbclass`` file. You need | ||
272 | to create that file next. | ||
273 | |||
274 | #. **Creating classes/base.bbclass:** BitBake uses class files to | ||
275 | provide common code and functionality. The minimally required class | ||
276 | for BitBake is the ``classes/base.bbclass`` file. The ``base`` class | ||
277 | is implicitly inherited by every recipe. BitBake looks for the class | ||
278 | in the ``classes`` directory of the project (i.e ``hello/classes`` | ||
279 | in this example). | ||
280 | |||
281 | Create the ``classes`` directory as follows: :: | ||
282 | |||
283 | $ cd $HOME/hello | ||
284 | $ mkdir classes | ||
285 | |||
286 | Move to the ``classes`` directory and then create the | ||
287 | ``base.bbclass`` file by inserting this single line: addtask build | ||
288 | The minimal task that BitBake runs is the ``do_build`` task. This is | ||
289 | all the example needs in order to build the project. Of course, the | ||
290 | ``base.bbclass`` can have much more depending on which build | ||
291 | environments BitBake is supporting. | ||
292 | |||
293 | #. **Run BitBake:** After making sure that the ``classes/base.bbclass`` | ||
294 | file exists, you can run the ``bitbake`` command again: :: | ||
295 | |||
296 | $ bitbake | ||
297 | Nothing to do. Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information. | ||
298 | |||
299 | BitBake is finally reporting | ||
300 | no errors. However, you can see that it really does not have | ||
301 | anything to do. You need to create a recipe that gives BitBake | ||
302 | something to do. | ||
303 | |||
304 | #. **Creating a Layer:** While it is not really necessary for such a | ||
305 | small example, it is good practice to create a layer in which to | ||
306 | keep your code separate from the general metadata used by BitBake. | ||
307 | Thus, this example creates and uses a layer called "mylayer". | ||
308 | |||
309 | .. note:: | ||
310 | |||
311 | You can find additional information on layers in the | ||
312 | ":ref:`bitbake-user-manual/bitbake-user-manual-intro:Layers`" section. | ||
313 | |||
314 | Minimally, you need a recipe file and a layer configuration file in | ||
315 | your layer. The configuration file needs to be in the ``conf`` | ||
316 | directory inside the layer. Use these commands to set up the layer | ||
317 | and the ``conf`` directory: :: | ||
318 | |||
319 | $ cd $HOME | ||
320 | $ mkdir mylayer | ||
321 | $ cd mylayer | ||
322 | $ mkdir conf | ||
323 | |||
324 | Move to the ``conf`` directory and create a ``layer.conf`` file that has the | ||
325 | following: :: | ||
326 | |||
327 | BBPATH .= ":${LAYERDIR}" | ||
328 | BBFILES += "${LAYERDIR}/\*.bb" | ||
329 | BBFILE_COLLECTIONS += "mylayer" | ||
330 | `BBFILE_PATTERN_mylayer := "^${LAYERDIR_RE}/" | ||
331 | |||
332 | For information on these variables, click on :term:`BBFILES`, | ||
333 | :term:`LAYERDIR`, :term:`BBFILE_COLLECTIONS` or :term:`BBFILE_PATTERN_mylayer <BBFILE_PATTERN>` | ||
334 | to go to the definitions in the glossary. | ||
335 | |||
336 | You need to create the recipe file next. Inside your layer at the | ||
337 | top-level, use an editor and create a recipe file named | ||
338 | ``printhello.bb`` that has the following: :: | ||
339 | |||
340 | DESCRIPTION = "Prints Hello World" | ||
341 | PN = 'printhello' | ||
342 | PV = '1' | ||
343 | |||
344 | python do_build() { | ||
345 | bb.plain("********************"); | ||
346 | bb.plain("* *"); | ||
347 | bb.plain("* Hello, World! *"); | ||
348 | bb.plain("* *"); | ||
349 | bb.plain("********************"); | ||
350 | } | ||
351 | |||
352 | The recipe file simply provides | ||
353 | a description of the recipe, the name, version, and the ``do_build`` | ||
354 | task, which prints out "Hello World" to the console. For more | ||
355 | information on :term:`DESCRIPTION`, :term:`PN` or :term:`PV` | ||
356 | follow the links to the glossary. | ||
357 | |||
358 | #. **Run BitBake With a Target:** Now that a BitBake target exists, run | ||
359 | the command and provide that target: :: | ||
360 | |||
361 | $ cd $HOME/hello | ||
362 | $ bitbake printhello | ||
363 | ERROR: no recipe files to build, check your BBPATH and BBFILES? | ||
364 | |||
365 | Summary: There was 1 ERROR message shown, returning a non-zero exit code. | ||
366 | |||
367 | We have created the layer with the recipe and | ||
368 | the layer configuration file but it still seems that BitBake cannot | ||
369 | find the recipe. BitBake needs a ``conf/bblayers.conf`` that lists | ||
370 | the layers for the project. Without this file, BitBake cannot find | ||
371 | the recipe. | ||
372 | |||
373 | #. **Creating conf/bblayers.conf:** BitBake uses the | ||
374 | ``conf/bblayers.conf`` file to locate layers needed for the project. | ||
375 | This file must reside in the ``conf`` directory of the project (i.e. | ||
376 | ``hello/conf`` for this example). | ||
377 | |||
378 | Set your working directory to the ``hello/conf`` directory and then | ||
379 | create the ``bblayers.conf`` file so that it contains the following: :: | ||
380 | |||
381 | BBLAYERS ?= " \ | ||
382 | /home/<you>/mylayer \ | ||
383 | " | ||
384 | |||
385 | You need to provide your own information for ``you`` in the file. | ||
386 | |||
387 | #. **Run BitBake With a Target:** Now that you have supplied the | ||
388 | ``bblayers.conf`` file, run the ``bitbake`` command and provide the | ||
389 | target: :: | ||
390 | |||
391 | $ bitbake printhello | ||
392 | Parsing recipes: 100% |##################################################################################| | ||
393 | Time: 00:00:00 | ||
394 | Parsing of 1 .bb files complete (0 cached, 1 parsed). 1 targets, 0 skipped, 0 masked, 0 errors. | ||
395 | NOTE: Resolving any missing task queue dependencies | ||
396 | NOTE: Preparing RunQueue | ||
397 | NOTE: Executing RunQueue Tasks | ||
398 | ******************** | ||
399 | * * | ||
400 | * Hello, World! * | ||
401 | * * | ||
402 | ******************** | ||
403 | NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded. | ||
404 | |||
405 | .. note:: | ||
406 | |||
407 | After the first execution, re-running bitbake printhello again will not | ||
408 | result in a BitBake run that prints the same console output. The reason | ||
409 | for this is that the first time the printhello.bb recipe's do_build task | ||
410 | executes successfully, BitBake writes a stamp file for the task. Thus, | ||
411 | the next time you attempt to run the task using that same bitbake | ||
412 | command, BitBake notices the stamp and therefore determines that the task | ||
413 | does not need to be re-run. If you delete the tmp directory or run | ||
414 | bitbake -c clean printhello and then re-run the build, the "Hello, | ||
415 | World!" message will be printed again. | ||