1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
|
.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
Writing a New Recipe
********************
Recipes (``.bb`` files) are fundamental components in the Yocto Project
environment. Each software component built by the OpenEmbedded build
system requires a recipe to define the component. This section describes
how to create, write, and test a new recipe.
.. note::
For information on variables that are useful for recipes and for
information about recipe naming issues, see the
":ref:`ref-manual/varlocality:recipes`" section of the Yocto Project
Reference Manual.
Overview
========
The following figure shows the basic process for creating a new recipe.
The remainder of the section provides details for the steps.
.. image:: figures/recipe-workflow.png
:align: center
:width: 50%
Locate or Automatically Create a Base Recipe
============================================
You can always write a recipe from scratch. However, there are three choices
that can help you quickly get started with a new recipe:
- ``devtool add``: A command that assists in creating a recipe and an
environment conducive to development.
- ``recipetool create``: A command provided by the Yocto Project that
automates creation of a base recipe based on the source files.
- *Existing Recipes:* Location and modification of an existing recipe
that is similar in function to the recipe you need.
.. note::
For information on recipe syntax, see the
":ref:`dev-manual/new-recipe:recipe syntax`" section.
Creating the Base Recipe Using ``devtool add``
----------------------------------------------
The ``devtool add`` command uses the same logic for auto-creating the
recipe as ``recipetool create``, which is listed below. Additionally,
however, ``devtool add`` sets up an environment that makes it easy for
you to patch the source and to make changes to the recipe as is often
necessary when adding a recipe to build a new piece of software to be
included in a build.
You can find a complete description of the ``devtool add`` command in
the ":ref:`sdk-manual/extensible:a closer look at \`\`devtool add\`\``" section
in the Yocto Project Application Development and the Extensible Software
Development Kit (eSDK) manual.
Creating the Base Recipe Using ``recipetool create``
----------------------------------------------------
``recipetool create`` automates creation of a base recipe given a set of
source code files. As long as you can extract or point to the source
files, the tool will construct a recipe and automatically configure all
pre-build information into the recipe. For example, suppose you have an
application that builds using Autotools. Creating the base recipe using
``recipetool`` results in a recipe that has the pre-build dependencies,
license requirements, and checksums configured.
To run the tool, you just need to be in your :term:`Build Directory` and
have sourced the build environment setup script (i.e.
:ref:`structure-core-script`). To get help on the tool, use the following
command::
$ recipetool -h
NOTE: Starting bitbake server...
usage: recipetool [-d] [-q] [--color COLOR] [-h] <subcommand> ...
OpenEmbedded recipe tool
options:
-d, --debug Enable debug output
-q, --quiet Print only errors
--color COLOR Colorize output (where COLOR is auto, always, never)
-h, --help show this help message and exit
subcommands:
create Create a new recipe
newappend Create a bbappend for the specified target in the specified
layer
setvar Set a variable within a recipe
appendfile Create/update a bbappend to replace a target file
appendsrcfiles Create/update a bbappend to add or replace source files
appendsrcfile Create/update a bbappend to add or replace a source file
Use recipetool <subcommand> --help to get help on a specific command
Running ``recipetool create -o OUTFILE`` creates the base recipe and
locates it properly in the layer that contains your source files.
Following are some syntax examples:
- Use this syntax to generate a recipe based on source. Once generated,
the recipe resides in the existing source code layer::
recipetool create -o OUTFILE source
- Use this syntax to generate a recipe using code that
you extract from source. The extracted code is placed in its own layer
defined by :term:`EXTERNALSRC`::
recipetool create -o OUTFILE -x EXTERNALSRC source
- Use this syntax to generate a recipe based on source. The options
direct ``recipetool`` to generate debugging information. Once generated,
the recipe resides in the existing source code layer::
recipetool create -d -o OUTFILE source
Locating and Using a Similar Recipe
-----------------------------------
Before writing a recipe from scratch, it is often useful to discover
whether someone else has already written one that meets (or comes close
to meeting) your needs. The Yocto Project and OpenEmbedded communities
maintain many recipes that might be candidates for what you are doing.
You can find a good central index of these recipes in the
:oe_layerindex:`OpenEmbedded Layer Index <>`.
Working from an existing recipe or a skeleton recipe is the best way to
get started. Here are some points on both methods:
- *Locate and modify a recipe that is close to what you want to do:*
This method works when you are familiar with the current recipe
space. The method does not work so well for those new to the Yocto
Project or writing recipes.
Some risks associated with this method are using a recipe that has
areas totally unrelated to what you are trying to accomplish with
your recipe, not recognizing areas of the recipe that you might have
to add from scratch, and so forth. All these risks stem from
unfamiliarity with the existing recipe space.
- *Use and modify the following skeleton recipe:* If for some reason
you do not want to use ``recipetool`` and you cannot find an existing
recipe that is close to meeting your needs, you can use the following
structure to provide the fundamental areas of a new recipe::
DESCRIPTION = ""
HOMEPAGE = ""
LICENSE = ""
SECTION = ""
DEPENDS = ""
LIC_FILES_CHKSUM = ""
SRC_URI = ""
Storing and Naming the Recipe
=============================
Once you have your base recipe, you should put it in your own layer and
name it appropriately. Locating it correctly ensures that the
OpenEmbedded build system can find it when you use BitBake to process
the recipe.
- *Storing Your Recipe:* The OpenEmbedded build system locates your
recipe through the layer's ``conf/layer.conf`` file and the
:term:`BBFILES` variable. This
variable sets up a path from which the build system can locate
recipes. Here is the typical use::
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
Consequently, you need to be sure you locate your new recipe inside
your layer such that it can be found.
You can find more information on how layers are structured in the
":ref:`dev-manual/layers:understanding and creating layers`" section.
- *Naming Your Recipe:* When you name your recipe, you need to follow
this naming convention::
basename_version.bb
Use lower-cased characters and do not include the reserved suffixes
``-native``, ``-cross``, ``-initial``, or ``-dev`` casually (i.e. do not use
them as part of your recipe name unless the string applies). Here are some
examples:
.. code-block:: none
cups_1.7.0.bb
gawk_4.0.2.bb
irssi_0.8.16-rc1.bb
Running a Build on the Recipe
=============================
Creating a new recipe is usually an iterative process that requires
using BitBake to process the recipe multiple times in order to
progressively discover and add information to the recipe file.
Assuming you have sourced the build environment setup script (i.e.
:ref:`structure-core-script`) and you are in the :term:`Build Directory`, use
BitBake to process your recipe. All you need to provide is the
``basename`` of the recipe as described in the previous section::
$ bitbake basename
During the build, the OpenEmbedded build system creates a temporary work
directory for each recipe
(``${``\ :term:`WORKDIR`\ ``}``)
where it keeps extracted source files, log files, intermediate
compilation and packaging files, and so forth.
The path to the per-recipe temporary work directory depends on the
context in which it is being built. The quickest way to find this path
is to have BitBake return it by running the following::
$ bitbake -e basename | grep ^WORKDIR=
As an example, assume a Source Directory
top-level folder named ``poky``, a default :term:`Build Directory` at
``poky/build``, and a ``qemux86-poky-linux`` machine target system.
Furthermore, suppose your recipe is named ``foo_1.3.0.bb``. In this
case, the work directory the build system uses to build the package
would be as follows::
poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0
Inside this directory you can find sub-directories such as ``image``,
``packages-split``, and ``temp``. After the build, you can examine these
to determine how well the build went.
.. note::
You can find log files for each task in the recipe's ``temp``
directory (e.g. ``poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0/temp``).
Log files are named ``log.taskname`` (e.g. ``log.do_configure``,
``log.do_fetch``, and ``log.do_compile``).
You can find more information about the build process in
":doc:`/overview-manual/development-environment`"
chapter of the Yocto Project Overview and Concepts Manual.
Fetching Code
=============
The first thing your recipe must do is specify how to fetch the source
files. Fetching is controlled mainly through the
:term:`SRC_URI` variable. Your recipe
must have a :term:`SRC_URI` variable that points to where the source is
located. For a graphical representation of source locations, see the
":ref:`overview-manual/concepts:sources`" section in
the Yocto Project Overview and Concepts Manual.
The :ref:`ref-tasks-fetch` task uses
the prefix of each entry in the :term:`SRC_URI` variable value to determine
which :ref:`fetcher <bitbake:bitbake-user-manual/bitbake-user-manual-fetching:fetchers>` to use to get your
source files. It is the :term:`SRC_URI` variable that triggers the fetcher.
The :ref:`ref-tasks-patch` task uses
the variable after source is fetched to apply patches. The OpenEmbedded
build system uses
:term:`FILESOVERRIDES` for
scanning directory locations for local files in :term:`SRC_URI`.
The :term:`SRC_URI` variable in your recipe must define each unique location
for your source files. It is good practice to not hard-code version
numbers in a URL used in :term:`SRC_URI`. Rather than hard-code these
values, use ``${``\ :term:`PV`\ ``}``,
which causes the fetch process to use the version specified in the
recipe filename. Specifying the version in this manner means that
upgrading the recipe to a future version is as simple as renaming the
recipe to match the new version.
Here is a simple example from the
``meta/recipes-devtools/strace/strace_5.5.bb`` recipe where the source
comes from a single tarball. Notice the use of the
:term:`PV` variable::
SRC_URI = "https://strace.io/files/${PV}/strace-${PV}.tar.xz \
Files mentioned in :term:`SRC_URI` whose names end in a typical archive
extension (e.g. ``.tar``, ``.tar.gz``, ``.tar.bz2``, ``.zip``, and so
forth), are automatically extracted during the
:ref:`ref-tasks-unpack` task. For
another example that specifies these types of files, see the
":ref:`dev-manual/new-recipe:autotooled package`" section.
Another way of specifying source is from an SCM. For Git repositories,
you must specify :term:`SRCREV` and you should specify :term:`PV` to include
the revision with :term:`SRCPV`. Here is an example from the recipe
``meta/recipes-core/musl/gcompat_git.bb``::
SRC_URI = "git://git.adelielinux.org/adelie/gcompat.git;protocol=https;branch=current"
PV = "1.0.0+1.1+git${SRCPV}"
SRCREV = "af5a49e489fdc04b9cf02547650d7aeaccd43793"
If your :term:`SRC_URI` statement includes URLs pointing to individual files
fetched from a remote server other than a version control system,
BitBake attempts to verify the files against checksums defined in your
recipe to ensure they have not been tampered with or otherwise modified
since the recipe was written. Two checksums are used:
``SRC_URI[md5sum]`` and ``SRC_URI[sha256sum]``.
If your :term:`SRC_URI` variable points to more than a single URL (excluding
SCM URLs), you need to provide the ``md5`` and ``sha256`` checksums for
each URL. For these cases, you provide a name for each URL as part of
the :term:`SRC_URI` and then reference that name in the subsequent checksum
statements. Here is an example combining lines from the files
``git.inc`` and ``git_2.24.1.bb``::
SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \
${KERNELORG_MIRROR}/software/scm/git/git-manpages-${PV}.tar.gz;name=manpages"
SRC_URI[tarball.md5sum] = "166bde96adbbc11c8843d4f8f4f9811b"
SRC_URI[tarball.sha256sum] = "ad5334956301c86841eb1e5b1bb20884a6bad89a10a6762c958220c7cf64da02"
SRC_URI[manpages.md5sum] = "31c2272a8979022497ba3d4202df145d"
SRC_URI[manpages.sha256sum] = "9a7ae3a093bea39770eb96ca3e5b40bff7af0b9f6123f089d7821d0e5b8e1230"
Proper values for ``md5`` and ``sha256`` checksums might be available
with other signatures on the download page for the upstream source (e.g.
``md5``, ``sha1``, ``sha256``, ``GPG``, and so forth). Because the
OpenEmbedded build system only deals with ``sha256sum`` and ``md5sum``,
you should verify all the signatures you find by hand.
If no :term:`SRC_URI` checksums are specified when you attempt to build the
recipe, or you provide an incorrect checksum, the build will produce an
error for each missing or incorrect checksum. As part of the error
message, the build system provides the checksum string corresponding to
the fetched file. Once you have the correct checksums, you can copy and
paste them into your recipe and then run the build again to continue.
.. note::
As mentioned, if the upstream source provides signatures for
verifying the downloaded source code, you should verify those
manually before setting the checksum values in the recipe and
continuing with the build.
This final example is a bit more complicated and is from the
``meta/recipes-sato/rxvt-unicode/rxvt-unicode_9.20.bb`` recipe. The
example's :term:`SRC_URI` statement identifies multiple files as the source
files for the recipe: a tarball, a patch file, a desktop file, and an icon::
SRC_URI = "http://dist.schmorp.de/rxvt-unicode/Attic/rxvt-unicode-${PV}.tar.bz2 \
file://xwc.patch \
file://rxvt.desktop \
file://rxvt.png"
When you specify local files using the ``file://`` URI protocol, the
build system fetches files from the local machine. The path is relative
to the :term:`FILESPATH` variable
and searches specific directories in a certain order:
``${``\ :term:`BP`\ ``}``,
``${``\ :term:`BPN`\ ``}``, and
``files``. The directories are assumed to be subdirectories of the
directory in which the recipe or append file resides. For another
example that specifies these types of files, see the
":ref:`dev-manual/new-recipe:single .c file package (hello world!)`" section.
The previous example also specifies a patch file. Patch files are files
whose names usually end in ``.patch`` or ``.diff`` but can end with
compressed suffixes such as ``diff.gz`` and ``patch.bz2``, for example.
The build system automatically applies patches as described in the
":ref:`dev-manual/new-recipe:patching code`" section.
Fetching Code Through Firewalls
-------------------------------
Some users are behind firewalls and need to fetch code through a proxy.
See the ":doc:`/ref-manual/faq`" chapter for advice.
Limiting the Number of Parallel Connections
-------------------------------------------
Some users are behind firewalls or use servers where the number of parallel
connections is limited. In such cases, you can limit the number of fetch
tasks being run in parallel by adding the following to your ``local.conf``
file::
do_fetch[number_threads] = "4"
Unpacking Code
==============
During the build, the
:ref:`ref-tasks-unpack` task unpacks
the source with ``${``\ :term:`S`\ ``}``
pointing to where it is unpacked.
If you are fetching your source files from an upstream source archived
tarball and the tarball's internal structure matches the common
convention of a top-level subdirectory named
``${``\ :term:`BPN`\ ``}-${``\ :term:`PV`\ ``}``,
then you do not need to set :term:`S`. However, if :term:`SRC_URI` specifies to
fetch source from an archive that does not use this convention, or from
an SCM like Git or Subversion, your recipe needs to define :term:`S`.
If processing your recipe using BitBake successfully unpacks the source
files, you need to be sure that the directory pointed to by ``${S}``
matches the structure of the source.
Patching Code
=============
Sometimes it is necessary to patch code after it has been fetched. Any
files mentioned in :term:`SRC_URI` whose names end in ``.patch`` or
``.diff`` or compressed versions of these suffixes (e.g. ``diff.gz`` are
treated as patches. The
:ref:`ref-tasks-patch` task
automatically applies these patches.
The build system should be able to apply patches with the "-p1" option
(i.e. one directory level in the path will be stripped off). If your
patch needs to have more directory levels stripped off, specify the
number of levels using the "striplevel" option in the :term:`SRC_URI` entry
for the patch. Alternatively, if your patch needs to be applied in a
specific subdirectory that is not specified in the patch file, use the
"patchdir" option in the entry.
As with all local files referenced in
:term:`SRC_URI` using ``file://``,
you should place patch files in a directory next to the recipe either
named the same as the base name of the recipe
(:term:`BP` and
:term:`BPN`) or "files".
Licensing
=========
Your recipe needs to have both the
:term:`LICENSE` and
:term:`LIC_FILES_CHKSUM`
variables:
- :term:`LICENSE`: This variable specifies the license for the software.
If you do not know the license under which the software you are
building is distributed, you should go to the source code and look
for that information. Typical files containing this information
include ``COPYING``, :term:`LICENSE`, and ``README`` files. You could
also find the information near the top of a source file. For example,
given a piece of software licensed under the GNU General Public
License version 2, you would set :term:`LICENSE` as follows::
LICENSE = "GPL-2.0-only"
The licenses you specify within :term:`LICENSE` can have any name as long
as you do not use spaces, since spaces are used as separators between
license names. For standard licenses, use the names of the files in
``meta/files/common-licenses/`` or the :term:`SPDXLICENSEMAP` flag names
defined in ``meta/conf/licenses.conf``.
- :term:`LIC_FILES_CHKSUM`: The OpenEmbedded build system uses this
variable to make sure the license text has not changed. If it has,
the build produces an error and it affords you the chance to figure
it out and correct the problem.
You need to specify all applicable licensing files for the software.
At the end of the configuration step, the build process will compare
the checksums of the files to be sure the text has not changed. Any
differences result in an error with the message containing the
current checksum. For more explanation and examples of how to set the
:term:`LIC_FILES_CHKSUM` variable, see the
":ref:`dev-manual/licenses:tracking license changes`" section.
To determine the correct checksum string, you can list the
appropriate files in the :term:`LIC_FILES_CHKSUM` variable with incorrect
md5 strings, attempt to build the software, and then note the
resulting error messages that will report the correct md5 strings.
See the ":ref:`dev-manual/new-recipe:fetching code`" section for
additional information.
Here is an example that assumes the software has a ``COPYING`` file::
LIC_FILES_CHKSUM = "file://COPYING;md5=xxx"
When you try to build the
software, the build system will produce an error and give you the
correct string that you can substitute into the recipe file for a
subsequent build.
Dependencies
============
Most software packages have a short list of other packages that they
require, which are called dependencies. These dependencies fall into two
main categories: build-time dependencies, which are required when the
software is built; and runtime dependencies, which are required to be
installed on the target in order for the software to run.
Within a recipe, you specify build-time dependencies using the
:term:`DEPENDS` variable. Although there are nuances,
items specified in :term:`DEPENDS` should be names of other
recipes. It is important that you specify all build-time dependencies
explicitly.
Another consideration is that configure scripts might automatically
check for optional dependencies and enable corresponding functionality
if those dependencies are found. If you wish to make a recipe that is
more generally useful (e.g. publish the recipe in a layer for others to
use), instead of hard-disabling the functionality, you can use the
:term:`PACKAGECONFIG` variable to allow functionality and the
corresponding dependencies to be enabled and disabled easily by other
users of the recipe.
Similar to build-time dependencies, you specify runtime dependencies
through a variable -
:term:`RDEPENDS`, which is
package-specific. All variables that are package-specific need to have
the name of the package added to the end as an override. Since the main
package for a recipe has the same name as the recipe, and the recipe's
name can be found through the
``${``\ :term:`PN`\ ``}`` variable, then
you specify the dependencies for the main package by setting
``RDEPENDS:${PN}``. If the package were named ``${PN}-tools``, then you
would set ``RDEPENDS:${PN}-tools``, and so forth.
Some runtime dependencies will be set automatically at packaging time.
These dependencies include any shared library dependencies (i.e. if a
package "example" contains "libexample" and another package "mypackage"
contains a binary that links to "libexample" then the OpenEmbedded build
system will automatically add a runtime dependency to "mypackage" on
"example"). See the
":ref:`overview-manual/concepts:automatically added runtime dependencies`"
section in the Yocto Project Overview and Concepts Manual for further
details.
Configuring the Recipe
======================
Most software provides some means of setting build-time configuration
options before compilation. Typically, setting these options is
accomplished by running a configure script with options, or by modifying
a build configuration file.
.. note::
As of Yocto Project Release 1.7, some of the core recipes that
package binary configuration scripts now disable the scripts due to
the scripts previously requiring error-prone path substitution. The
OpenEmbedded build system uses ``pkg-config`` now, which is much more
robust. You can find a list of the ``*-config`` scripts that are disabled
in the ":ref:`migration-1.7-binary-configuration-scripts-disabled`" section
in the Yocto Project Reference Manual.
A major part of build-time configuration is about checking for
build-time dependencies and possibly enabling optional functionality as
a result. You need to specify any build-time dependencies for the
software you are building in your recipe's
:term:`DEPENDS` value, in terms of
other recipes that satisfy those dependencies. You can often find
build-time or runtime dependencies described in the software's
documentation.
The following list provides configuration items of note based on how
your software is built:
- *Autotools:* If your source files have a ``configure.ac`` file, then
your software is built using Autotools. If this is the case, you just
need to modify the configuration.
When using Autotools, your recipe needs to inherit the
:ref:`ref-classes-autotools` class and it does not have to
contain a :ref:`ref-tasks-configure` task. However, you might still want to
make some adjustments. For example, you can set :term:`EXTRA_OECONF` or
:term:`PACKAGECONFIG_CONFARGS` to pass any needed configure options that
are specific to the recipe.
- *CMake:* If your source files have a ``CMakeLists.txt`` file, then
your software is built using CMake. If this is the case, you just
need to modify the configuration.
When you use CMake, your recipe needs to inherit the
:ref:`ref-classes-cmake` class and it does not have to contain a
:ref:`ref-tasks-configure` task. You can make some adjustments by setting
:term:`EXTRA_OECMAKE` to pass any needed configure options that are
specific to the recipe.
.. note::
If you need to install one or more custom CMake toolchain files
that are supplied by the application you are building, install the
files to ``${D}${datadir}/cmake/Modules`` during :ref:`ref-tasks-install`.
- *Other:* If your source files do not have a ``configure.ac`` or
``CMakeLists.txt`` file, then your software is built using some
method other than Autotools or CMake. If this is the case, you
normally need to provide a
:ref:`ref-tasks-configure` task
in your recipe unless, of course, there is nothing to configure.
Even if your software is not being built by Autotools or CMake, you
still might not need to deal with any configuration issues. You need
to determine if configuration is even a required step. You might need
to modify a Makefile or some configuration file used for the build to
specify necessary build options. Or, perhaps you might need to run a
provided, custom configure script with the appropriate options.
For the case involving a custom configure script, you would run
``./configure --help`` and look for the options you need to set.
Once configuration succeeds, it is always good practice to look at the
``log.do_configure`` file to ensure that the appropriate options have
been enabled and no additional build-time dependencies need to be added
to :term:`DEPENDS`. For example, if the configure script reports that it
found something not mentioned in :term:`DEPENDS`, or that it did not find
something that it needed for some desired optional functionality, then
you would need to add those to :term:`DEPENDS`. Looking at the log might
also reveal items being checked for, enabled, or both that you do not
want, or items not being found that are in :term:`DEPENDS`, in which case
you would need to look at passing extra options to the configure script
as needed. For reference information on configure options specific to
the software you are building, you can consult the output of the
``./configure --help`` command within ``${S}`` or consult the software's
upstream documentation.
Using Headers to Interface with Devices
=======================================
If your recipe builds an application that needs to communicate with some
device or needs an API into a custom kernel, you will need to provide
appropriate header files. Under no circumstances should you ever modify
the existing
``meta/recipes-kernel/linux-libc-headers/linux-libc-headers.inc`` file.
These headers are used to build ``libc`` and must not be compromised
with custom or machine-specific header information. If you customize
``libc`` through modified headers all other applications that use
``libc`` thus become affected.
.. note::
Never copy and customize the ``libc`` header file (i.e.
``meta/recipes-kernel/linux-libc-headers/linux-libc-headers.inc``).
The correct way to interface to a device or custom kernel is to use a
separate package that provides the additional headers for the driver or
other unique interfaces. When doing so, your application also becomes
responsible for creating a dependency on that specific provider.
Consider the following:
- Never modify ``linux-libc-headers.inc``. Consider that file to be
part of the ``libc`` system, and not something you use to access the
kernel directly. You should access ``libc`` through specific ``libc``
calls.
- Applications that must talk directly to devices should either provide
necessary headers themselves, or establish a dependency on a special
headers package that is specific to that driver.
For example, suppose you want to modify an existing header that adds I/O
control or network support. If the modifications are used by a small
number programs, providing a unique version of a header is easy and has
little impact. When doing so, bear in mind the guidelines in the
previous list.
.. note::
If for some reason your changes need to modify the behavior of the ``libc``,
and subsequently all other applications on the system, use a ``.bbappend``
to modify the ``linux-kernel-headers.inc`` file. However, take care to not
make the changes machine specific.
Consider a case where your kernel is older and you need an older
``libc`` ABI. The headers installed by your recipe should still be a
standard mainline kernel, not your own custom one.
When you use custom kernel headers you need to get them from
:term:`STAGING_KERNEL_DIR`,
which is the directory with kernel headers that are required to build
out-of-tree modules. Your recipe will also need the following::
do_configure[depends] += "virtual/kernel:do_shared_workdir"
Compilation
===========
During a build, the :ref:`ref-tasks-compile` task happens after source is fetched,
unpacked, and configured. If the recipe passes through :ref:`ref-tasks-compile`
successfully, nothing needs to be done.
However, if the compile step fails, you need to diagnose the failure.
Here are some common issues that cause failures.
.. note::
For cases where improper paths are detected for configuration files
or for when libraries/headers cannot be found, be sure you are using
the more robust ``pkg-config``. See the note in section
":ref:`dev-manual/new-recipe:Configuring the Recipe`" for additional information.
- *Parallel build failures:* These failures manifest themselves as
intermittent errors, or errors reporting that a file or directory
that should be created by some other part of the build process could
not be found. This type of failure can occur even if, upon
inspection, the file or directory does exist after the build has
failed, because that part of the build process happened in the wrong
order.
To fix the problem, you need to either satisfy the missing dependency
in the Makefile or whatever script produced the Makefile, or (as a
workaround) set :term:`PARALLEL_MAKE` to an empty string::
PARALLEL_MAKE = ""
For information on parallel Makefile issues, see the
":ref:`dev-manual/debugging:debugging parallel make races`" section.
- *Improper host path usage:* This failure applies to recipes building
for the target or ":ref:`ref-classes-nativesdk`" only. The
failure occurs when the compilation process uses improper headers,
libraries, or other files from the host system when cross-compiling for
the target.
To fix the problem, examine the ``log.do_compile`` file to identify
the host paths being used (e.g. ``/usr/include``, ``/usr/lib``, and
so forth) and then either add configure options, apply a patch, or do
both.
- *Failure to find required libraries/headers:* If a build-time
dependency is missing because it has not been declared in
:term:`DEPENDS`, or because the
dependency exists but the path used by the build process to find the
file is incorrect and the configure step did not detect it, the
compilation process could fail. For either of these failures, the
compilation process notes that files could not be found. In these
cases, you need to go back and add additional options to the
configure script as well as possibly add additional build-time
dependencies to :term:`DEPENDS`.
Occasionally, it is necessary to apply a patch to the source to
ensure the correct paths are used. If you need to specify paths to
find files staged into the sysroot from other recipes, use the
variables that the OpenEmbedded build system provides (e.g.
:term:`STAGING_BINDIR`, :term:`STAGING_INCDIR`, :term:`STAGING_DATADIR`, and so
forth).
Installing
==========
During :ref:`ref-tasks-install`, the task copies the built files along with their
hierarchy to locations that would mirror their locations on the target
device. The installation process copies files from the
``${``\ :term:`S`\ ``}``,
``${``\ :term:`B`\ ``}``, and
``${``\ :term:`WORKDIR`\ ``}``
directories to the ``${``\ :term:`D`\ ``}``
directory to create the structure as it should appear on the target
system.
How your software is built affects what you must do to be sure your
software is installed correctly. The following list describes what you
must do for installation depending on the type of build system used by
the software being built:
- *Autotools and CMake:* If the software your recipe is building uses
Autotools or CMake, the OpenEmbedded build system understands how to
install the software. Consequently, you do not have to have a
:ref:`ref-tasks-install` task as part of your recipe. You just need to make
sure the install portion of the build completes with no issues.
However, if you wish to install additional files not already being
installed by ``make install``, you should do this using a
``do_install:append`` function using the install command as described
in the "Manual" bulleted item later in this list.
- *Other (using* ``make install``\ *)*: You need to define a :ref:`ref-tasks-install`
function in your recipe. The function should call
``oe_runmake install`` and will likely need to pass in the
destination directory as well. How you pass that path is dependent on
how the ``Makefile`` being run is written (e.g. ``DESTDIR=${D}``,
``PREFIX=${D}``, ``INSTALLROOT=${D}``, and so forth).
For an example recipe using ``make install``, see the
":ref:`dev-manual/new-recipe:makefile-based package`" section.
- *Manual:* You need to define a :ref:`ref-tasks-install` function in your
recipe. The function must first use ``install -d`` to create the
directories under
``${``\ :term:`D`\ ``}``. Once the
directories exist, your function can use ``install`` to manually
install the built software into the directories.
You can find more information on ``install`` at
https://www.gnu.org/software/coreutils/manual/html_node/install-invocation.html.
For the scenarios that do not use Autotools or CMake, you need to track
the installation and diagnose and fix any issues until everything
installs correctly. You need to look in the default location of
``${D}``, which is ``${WORKDIR}/image``, to be sure your files have been
installed correctly.
.. note::
- During the installation process, you might need to modify some of
the installed files to suit the target layout. For example, you
might need to replace hard-coded paths in an initscript with
values of variables provided by the build system, such as
replacing ``/usr/bin/`` with ``${bindir}``. If you do perform such
modifications during :ref:`ref-tasks-install`, be sure to modify the
destination file after copying rather than before copying.
Modifying after copying ensures that the build system can
re-execute :ref:`ref-tasks-install` if needed.
- ``oe_runmake install``, which can be run directly or can be run
indirectly by the :ref:`ref-classes-autotools` and
:ref:`ref-classes-cmake` classes, runs ``make install`` in parallel.
Sometimes, a Makefile can have missing dependencies between targets that
can result in race conditions. If you experience intermittent failures
during :ref:`ref-tasks-install`, you might be able to work around them by
disabling parallel Makefile installs by adding the following to the
recipe::
PARALLEL_MAKEINST = ""
See :term:`PARALLEL_MAKEINST` for additional information.
- If you need to install one or more custom CMake toolchain files
that are supplied by the application you are building, install the
files to ``${D}${datadir}/cmake/Modules`` during
:ref:`ref-tasks-install`.
Enabling System Services
========================
If you want to install a service, which is a process that usually starts
on boot and runs in the background, then you must include some
additional definitions in your recipe.
If you are adding services and the service initialization script or the
service file itself is not installed, you must provide for that
installation in your recipe using a ``do_install:append`` function. If
your recipe already has a :ref:`ref-tasks-install` function, update the function
near its end rather than adding an additional ``do_install:append``
function.
When you create the installation for your services, you need to
accomplish what is normally done by ``make install``. In other words,
make sure your installation arranges the output similar to how it is
arranged on the target system.
The OpenEmbedded build system provides support for starting services two
different ways:
- *SysVinit:* SysVinit is a system and service manager that manages the
init system used to control the very basic functions of your system.
The init program is the first program started by the Linux kernel
when the system boots. Init then controls the startup, running and
shutdown of all other programs.
To enable a service using SysVinit, your recipe needs to inherit the
:ref:`ref-classes-update-rc.d` class. The class helps
facilitate safely installing the package on the target.
You will need to set the
:term:`INITSCRIPT_PACKAGES`,
:term:`INITSCRIPT_NAME`,
and
:term:`INITSCRIPT_PARAMS`
variables within your recipe.
- *systemd:* System Management Daemon (systemd) was designed to replace
SysVinit and to provide enhanced management of services. For more
information on systemd, see the systemd homepage at
https://freedesktop.org/wiki/Software/systemd/.
To enable a service using systemd, your recipe needs to inherit the
:ref:`ref-classes-systemd` class. See the ``systemd.bbclass`` file
located in your :term:`Source Directory` section for more information.
Packaging
=========
Successful packaging is a combination of automated processes performed
by the OpenEmbedded build system and some specific steps you need to
take. The following list describes the process:
- *Splitting Files*: The :ref:`ref-tasks-package` task splits the files produced
by the recipe into logical components. Even software that produces a
single binary might still have debug symbols, documentation, and
other logical components that should be split out. The :ref:`ref-tasks-package`
task ensures that files are split up and packaged correctly.
- *Running QA Checks*: The :ref:`ref-classes-insane` class adds a
step to the package generation process so that output quality
assurance checks are generated by the OpenEmbedded build system. This
step performs a range of checks to be sure the build's output is free
of common problems that show up during runtime. For information on
these checks, see the :ref:`ref-classes-insane` class and
the ":ref:`ref-manual/qa-checks:qa error and warning messages`"
chapter in the Yocto Project Reference Manual.
- *Hand-Checking Your Packages*: After you build your software, you
need to be sure your packages are correct. Examine the
``${``\ :term:`WORKDIR`\ ``}/packages-split``
directory and make sure files are where you expect them to be. If you
discover problems, you can set
:term:`PACKAGES`,
:term:`FILES`,
``do_install(:append)``, and so forth as needed.
- *Splitting an Application into Multiple Packages*: If you need to
split an application into several packages, see the
":ref:`dev-manual/new-recipe:splitting an application into multiple packages`"
section for an example.
- *Installing a Post-Installation Script*: For an example showing how
to install a post-installation script, see the
":ref:`dev-manual/new-recipe:post-installation scripts`" section.
- *Marking Package Architecture*: Depending on what your recipe is
building and how it is configured, it might be important to mark the
packages produced as being specific to a particular machine, or to
mark them as not being specific to a particular machine or
architecture at all.
By default, packages apply to any machine with the same architecture
as the target machine. When a recipe produces packages that are
machine-specific (e.g. the
:term:`MACHINE` value is passed
into the configure script or a patch is applied only for a particular
machine), you should mark them as such by adding the following to the
recipe::
PACKAGE_ARCH = "${MACHINE_ARCH}"
On the other hand, if the recipe produces packages that do not
contain anything specific to the target machine or architecture at
all (e.g. recipes that simply package script files or configuration
files), you should use the :ref:`ref-classes-allarch` class to
do this for you by adding this to your recipe::
inherit allarch
Ensuring that the package architecture is correct is not critical
while you are doing the first few builds of your recipe. However, it
is important in order to ensure that your recipe rebuilds (or does
not rebuild) appropriately in response to changes in configuration,
and to ensure that you get the appropriate packages installed on the
target machine, particularly if you run separate builds for more than
one target machine.
Sharing Files Between Recipes
=============================
Recipes often need to use files provided by other recipes on the build
host. For example, an application linking to a common library needs
access to the library itself and its associated headers. The way this
access is accomplished is by populating a sysroot with files. Each
recipe has two sysroots in its work directory, one for target files
(``recipe-sysroot``) and one for files that are native to the build host
(``recipe-sysroot-native``).
.. note::
You could find the term "staging" used within the Yocto project
regarding files populating sysroots (e.g. the :term:`STAGING_DIR`
variable).
Recipes should never populate the sysroot directly (i.e. write files
into sysroot). Instead, files should be installed into standard
locations during the
:ref:`ref-tasks-install` task within
the ``${``\ :term:`D`\ ``}`` directory. The
reason for this limitation is that almost all files that populate the
sysroot are cataloged in manifests in order to ensure the files can be
removed later when a recipe is either modified or removed. Thus, the
sysroot is able to remain free from stale files.
A subset of the files installed by the :ref:`ref-tasks-install` task are
used by the :ref:`ref-tasks-populate_sysroot` task as defined by the
:term:`SYSROOT_DIRS` variable to automatically populate the sysroot. It
is possible to modify the list of directories that populate the sysroot.
The following example shows how you could add the ``/opt`` directory to
the list of directories within a recipe::
SYSROOT_DIRS += "/opt"
.. note::
The `/sysroot-only` is to be used by recipes that generate artifacts
that are not included in the target filesystem, allowing them to share
these artifacts without needing to use the :term:`DEPLOY_DIR`.
For a more complete description of the :ref:`ref-tasks-populate_sysroot`
task and its associated functions, see the
:ref:`staging <ref-classes-staging>` class.
Using Virtual Providers
=======================
Prior to a build, if you know that several different recipes provide the
same functionality, you can use a virtual provider (i.e. ``virtual/*``)
as a placeholder for the actual provider. The actual provider is
determined at build-time.
A common scenario where a virtual provider is used would be for the kernel
recipe. Suppose you have three kernel recipes whose :term:`PN` values map to
``kernel-big``, ``kernel-mid``, and ``kernel-small``. Furthermore, each of
these recipes in some way uses a :term:`PROVIDES` statement that essentially
identifies itself as being able to provide ``virtual/kernel``. Here is one way
through the :ref:`ref-classes-kernel` class::
PROVIDES += "virtual/kernel"
Any recipe that inherits the :ref:`ref-classes-kernel` class is
going to utilize a :term:`PROVIDES` statement that identifies that recipe as
being able to provide the ``virtual/kernel`` item.
Now comes the time to actually build an image and you need a kernel
recipe, but which one? You can configure your build to call out the
kernel recipe you want by using the :term:`PREFERRED_PROVIDER` variable. As
an example, consider the :yocto_git:`x86-base.inc
</poky/tree/meta/conf/machine/include/x86/x86-base.inc>` include file, which is a
machine (i.e. :term:`MACHINE`) configuration file. This include file is the
reason all x86-based machines use the ``linux-yocto`` kernel. Here are the
relevant lines from the include file::
PREFERRED_PROVIDER_virtual/kernel ??= "linux-yocto"
PREFERRED_VERSION_linux-yocto ??= "4.15%"
When you use a virtual provider, you do not have to "hard code" a recipe
name as a build dependency. You can use the
:term:`DEPENDS` variable to state the
build is dependent on ``virtual/kernel`` for example::
DEPENDS = "virtual/kernel"
During the build, the OpenEmbedded build system picks
the correct recipe needed for the ``virtual/kernel`` dependency based on
the :term:`PREFERRED_PROVIDER` variable. If you want to use the small kernel
mentioned at the beginning of this section, configure your build as
follows::
PREFERRED_PROVIDER_virtual/kernel ??= "kernel-small"
.. note::
Any recipe that :term:`PROVIDES` a ``virtual/*`` item that is ultimately not
selected through :term:`PREFERRED_PROVIDER` does not get built. Preventing these
recipes from building is usually the desired behavior since this mechanism's
purpose is to select between mutually exclusive alternative providers.
The following lists specific examples of virtual providers:
- ``virtual/kernel``: Provides the name of the kernel recipe to use
when building a kernel image.
- ``virtual/bootloader``: Provides the name of the bootloader to use
when building an image.
- ``virtual/libgbm``: Provides ``gbm.pc``.
- ``virtual/egl``: Provides ``egl.pc`` and possibly ``wayland-egl.pc``.
- ``virtual/libgl``: Provides ``gl.pc`` (i.e. libGL).
- ``virtual/libgles1``: Provides ``glesv1_cm.pc`` (i.e. libGLESv1_CM).
- ``virtual/libgles2``: Provides ``glesv2.pc`` (i.e. libGLESv2).
.. note::
Virtual providers only apply to build time dependencies specified with
:term:`PROVIDES` and :term:`DEPENDS`. They do not apply to runtime
dependencies specified with :term:`RPROVIDES` and :term:`RDEPENDS`.
Properly Versioning Pre-Release Recipes
=======================================
Sometimes the name of a recipe can lead to versioning problems when the
recipe is upgraded to a final release. For example, consider the
``irssi_0.8.16-rc1.bb`` recipe file in the list of example recipes in
the ":ref:`dev-manual/new-recipe:storing and naming the recipe`" section.
This recipe is at a release candidate stage (i.e. "rc1"). When the recipe is
released, the recipe filename becomes ``irssi_0.8.16.bb``. The version
change from ``0.8.16-rc1`` to ``0.8.16`` is seen as a decrease by the
build system and package managers, so the resulting packages will not
correctly trigger an upgrade.
In order to ensure the versions compare properly, the recommended
convention is to set :term:`PV` within the
recipe to "previous_version+current_version". You can use an additional
variable so that you can use the current version elsewhere. Here is an
example::
REALPV = "0.8.16-rc1"
PV = "0.8.15+${REALPV}"
Post-Installation Scripts
=========================
Post-installation scripts run immediately after installing a package on
the target or during image creation when a package is included in an
image. To add a post-installation script to a package, add a
``pkg_postinst:``\ `PACKAGENAME`\ ``()`` function to the recipe file
(``.bb``) and replace `PACKAGENAME` with the name of the package you want
to attach to the ``postinst`` script. To apply the post-installation
script to the main package for the recipe, which is usually what is
required, specify
``${``\ :term:`PN`\ ``}`` in place of
PACKAGENAME.
A post-installation function has the following structure::
pkg_postinst:PACKAGENAME() {
# Commands to carry out
}
The script defined in the post-installation function is called when the
root filesystem is created. If the script succeeds, the package is
marked as installed.
.. note::
Any RPM post-installation script that runs on the target should
return a 0 exit code. RPM does not allow non-zero exit codes for
these scripts, and the RPM package manager will cause the package to
fail installation on the target.
Sometimes it is necessary for the execution of a post-installation
script to be delayed until the first boot. For example, the script might
need to be executed on the device itself. To delay script execution
until boot time, you must explicitly mark post installs to defer to the
target. You can use ``pkg_postinst_ontarget()`` or call
``postinst_intercept delay_to_first_boot`` from ``pkg_postinst()``. Any
failure of a ``pkg_postinst()`` script (including exit 1) triggers an
error during the
:ref:`ref-tasks-rootfs` task.
If you have recipes that use ``pkg_postinst`` function and they require
the use of non-standard native tools that have dependencies during
root filesystem construction, you need to use the
:term:`PACKAGE_WRITE_DEPS`
variable in your recipe to list these tools. If you do not use this
variable, the tools might be missing and execution of the
post-installation script is deferred until first boot. Deferring the
script to the first boot is undesirable and impossible for read-only
root filesystems.
.. note::
There is equivalent support for pre-install, pre-uninstall, and post-uninstall
scripts by way of ``pkg_preinst``, ``pkg_prerm``, and ``pkg_postrm``,
respectively. These scrips work in exactly the same way as does
``pkg_postinst`` with the exception that they run at different times. Also,
because of when they run, they are not applicable to being run at image
creation time like ``pkg_postinst``.
Testing
=======
The final step for completing your recipe is to be sure that the
software you built runs correctly. To accomplish runtime testing, add
the build's output packages to your image and test them on the target.
For information on how to customize your image by adding specific
packages, see ":ref:`dev-manual/customizing-images:customizing images`" section.
Examples
========
To help summarize how to write a recipe, this section provides some
examples given various scenarios:
- Recipes that use local files
- Using an Autotooled package
- Using a Makefile-based package
- Splitting an application into multiple packages
- Adding binaries to an image
Single .c File Package (Hello World!)
-------------------------------------
Building an application from a single file that is stored locally (e.g.
under ``files``) requires a recipe that has the file listed in the
:term:`SRC_URI` variable. Additionally, you need to manually write the
:ref:`ref-tasks-compile` and :ref:`ref-tasks-install` tasks. The :term:`S` variable defines the
directory containing the source code, which is set to
:term:`WORKDIR` in this case --- the
directory BitBake uses for the build::
SUMMARY = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://helloworld.c"
S = "${WORKDIR}"
do_compile() {
${CC} ${LDFLAGS} helloworld.c -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}
By default, the ``helloworld``, ``helloworld-dbg``, and
``helloworld-dev`` packages are built. For information on how to
customize the packaging process, see the
":ref:`dev-manual/new-recipe:splitting an application into multiple packages`"
section.
Autotooled Package
------------------
Applications that use Autotools such as ``autoconf`` and ``automake``
require a recipe that has a source archive listed in :term:`SRC_URI` and
also inherit the :ref:`ref-classes-autotools` class,
which contains the definitions of all the steps needed to build an
Autotool-based application. The result of the build is automatically
packaged. And, if the application uses NLS for localization, packages
with local information are generated (one package per language).
Following is one example: (``hello_2.3.bb``)::
SUMMARY = "GNU Helloworld application"
SECTION = "examples"
LICENSE = "GPL-2.0-or-later"
LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
SRC_URI = "${GNU_MIRROR}/hello/hello-${PV}.tar.gz"
inherit autotools gettext
The variable :term:`LIC_FILES_CHKSUM` is used to track source license
changes as described in the
":ref:`dev-manual/licenses:tracking license changes`" section in
the Yocto Project Overview and Concepts Manual. You can quickly create
Autotool-based recipes in a manner similar to the previous example.
Makefile-Based Package
----------------------
Applications that use GNU ``make`` also require a recipe that has the
source archive listed in :term:`SRC_URI`. You do not need to add a
:ref:`ref-tasks-compile` step since by default BitBake starts the ``make`` command
to compile the application. If you need additional ``make`` options, you
should store them in the
:term:`EXTRA_OEMAKE` or
:term:`PACKAGECONFIG_CONFARGS`
variables. BitBake passes these options into the GNU ``make``
invocation. Note that a :ref:`ref-tasks-install` task is still required.
Otherwise, BitBake runs an empty :ref:`ref-tasks-install` task by default.
Some applications might require extra parameters to be passed to the
compiler. For example, the application might need an additional header
path. You can accomplish this by adding to the :term:`CFLAGS` variable. The
following example shows this::
CFLAGS:prepend = "-I ${S}/include "
In the following example, ``lz4`` is a makefile-based package::
SUMMARY = "Extremely Fast Compression algorithm"
DESCRIPTION = "LZ4 is a very fast lossless compression algorithm, providing compression speed at 400 MB/s per core, scalable with multi-cores CPU. It also features an extremely fast decoder, with speed in multiple GB/s per core, typically reaching RAM speed limits on multi-core systems."
HOMEPAGE = "https://github.com/lz4/lz4"
LICENSE = "BSD-2-Clause | GPL-2.0-only"
LIC_FILES_CHKSUM = "file://lib/LICENSE;md5=ebc2ea4814a64de7708f1571904b32cc \
file://programs/COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
file://LICENSE;md5=d57c0d21cb917fb4e0af2454aa48b956 \
"
PE = "1"
SRCREV = "d44371841a2f1728a3f36839fd4b7e872d0927d3"
SRC_URI = "git://github.com/lz4/lz4.git;branch=release;protocol=https \
file://CVE-2021-3520.patch \
"
UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>.*)"
S = "${WORKDIR}/git"
# Fixed in r118, which is larger than the current version.
CVE_CHECK_IGNORE += "CVE-2014-4715"
EXTRA_OEMAKE = "PREFIX=${prefix} CC='${CC}' CFLAGS='${CFLAGS}' DESTDIR=${D} LIBDIR=${libdir} INCLUDEDIR=${includedir} BUILD_STATIC=no"
do_install() {
oe_runmake install
}
BBCLASSEXTEND = "native nativesdk"
Splitting an Application into Multiple Packages
-----------------------------------------------
You can use the variables :term:`PACKAGES` and :term:`FILES` to split an
application into multiple packages.
Following is an example that uses the ``libxpm`` recipe. By default,
this recipe generates a single package that contains the library along
with a few binaries. You can modify the recipe to split the binaries
into separate packages::
require xorg-lib-common.inc
SUMMARY = "Xpm: X Pixmap extension library"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://COPYING;md5=51f4270b012ecd4ab1a164f5f4ed6cf7"
DEPENDS += "libxext libsm libxt"
PE = "1"
XORG_PN = "libXpm"
PACKAGES =+ "sxpm cxpm"
FILES:cxpm = "${bindir}/cxpm"
FILES:sxpm = "${bindir}/sxpm"
In the previous example, we want to ship the ``sxpm`` and ``cxpm``
binaries in separate packages. Since ``bindir`` would be packaged into
the main :term:`PN` package by default, we prepend the :term:`PACKAGES` variable
so additional package names are added to the start of list. This results
in the extra ``FILES:*`` variables then containing information that
define which files and directories go into which packages. Files
included by earlier packages are skipped by latter packages. Thus, the
main :term:`PN` package does not include the above listed files.
Packaging Externally Produced Binaries
--------------------------------------
Sometimes, you need to add pre-compiled binaries to an image. For
example, suppose that there are binaries for proprietary code,
created by a particular division of a company. Your part of the company
needs to use those binaries as part of an image that you are building
using the OpenEmbedded build system. Since you only have the binaries
and not the source code, you cannot use a typical recipe that expects to
fetch the source specified in
:term:`SRC_URI` and then compile it.
One method is to package the binaries and then install them as part of
the image. Generally, it is not a good idea to package binaries since,
among other things, it can hinder the ability to reproduce builds and
could lead to compatibility problems with ABI in the future. However,
sometimes you have no choice.
The easiest solution is to create a recipe that uses the
:ref:`ref-classes-bin-package` class and to be sure that you are using default
locations for build artifacts. In most cases, the
:ref:`ref-classes-bin-package` class handles "skipping" the configure and
compile steps as well as sets things up to grab packages from the appropriate
area. In particular, this class sets ``noexec`` on both the
:ref:`ref-tasks-configure` and :ref:`ref-tasks-compile` tasks, sets
``FILES:${PN}`` to "/" so that it picks up all files, and sets up a
:ref:`ref-tasks-install` task, which effectively copies all files from ``${S}``
to ``${D}``. The :ref:`ref-classes-bin-package` class works well when the files
extracted into ``${S}`` are already laid out in the way they should be laid out
on the target. For more information on these variables, see the :term:`FILES`,
:term:`PN`, :term:`S`, and :term:`D` variables in the Yocto Project Reference
Manual's variable glossary.
.. note::
- Using :term:`DEPENDS` is a good
idea even for components distributed in binary form, and is often
necessary for shared libraries. For a shared library, listing the
library dependencies in :term:`DEPENDS` makes sure that the libraries
are available in the staging sysroot when other recipes link
against the library, which might be necessary for successful
linking.
- Using :term:`DEPENDS` also allows runtime dependencies between
packages to be added automatically. See the
":ref:`overview-manual/concepts:automatically added runtime dependencies`"
section in the Yocto Project Overview and Concepts Manual for more
information.
If you cannot use the :ref:`ref-classes-bin-package` class, you need to be sure you are
doing the following:
- Create a recipe where the
:ref:`ref-tasks-configure` and
:ref:`ref-tasks-compile` tasks do
nothing: It is usually sufficient to just not define these tasks in
the recipe, because the default implementations do nothing unless a
Makefile is found in
``${``\ :term:`S`\ ``}``.
If ``${S}`` might contain a Makefile, or if you inherit some class
that replaces :ref:`ref-tasks-configure` and :ref:`ref-tasks-compile` with custom
versions, then you can use the
``[``\ :ref:`noexec <bitbake-user-manual/bitbake-user-manual-metadata:variable flags>`\ ``]``
flag to turn the tasks into no-ops, as follows::
do_configure[noexec] = "1"
do_compile[noexec] = "1"
Unlike
:ref:`bitbake:bitbake-user-manual/bitbake-user-manual-metadata:deleting a task`,
using the flag preserves the dependency chain from the
:ref:`ref-tasks-fetch`,
:ref:`ref-tasks-unpack`, and
:ref:`ref-tasks-patch` tasks to the
:ref:`ref-tasks-install` task.
- Make sure your :ref:`ref-tasks-install` task installs the binaries
appropriately.
- Ensure that you set up :term:`FILES`
(usually
``FILES:${``\ :term:`PN`\ ``}``) to
point to the files you have installed, which of course depends on
where you have installed them and whether those files are in
different locations than the defaults.
Following Recipe Style Guidelines
=================================
When writing recipes, it is good to conform to existing style
guidelines. The :oe_wiki:`OpenEmbedded Styleguide </Styleguide>` wiki page
provides rough guidelines for preferred recipe style.
It is common for existing recipes to deviate a bit from this style.
However, aiming for at least a consistent style is a good idea. Some
practices, such as omitting spaces around ``=`` operators in assignments
or ordering recipe components in an erratic way, are widely seen as poor
style.
Recipe Syntax
=============
Understanding recipe file syntax is important for writing recipes. The
following list overviews the basic items that make up a BitBake recipe
file. For more complete BitBake syntax descriptions, see the
":doc:`bitbake:bitbake-user-manual/bitbake-user-manual-metadata`"
chapter of the BitBake User Manual.
- *Variable Assignments and Manipulations:* Variable assignments allow
a value to be assigned to a variable. The assignment can be static
text or might include the contents of other variables. In addition to
the assignment, appending and prepending operations are also
supported.
The following example shows some of the ways you can use variables in
recipes::
S = "${WORKDIR}/postfix-${PV}"
CFLAGS += "-DNO_ASM"
CFLAGS:append = " --enable-important-feature"
- *Functions:* Functions provide a series of actions to be performed.
You usually use functions to override the default implementation of a
task function or to complement a default function (i.e. append or
prepend to an existing function). Standard functions use ``sh`` shell
syntax, although access to OpenEmbedded variables and internal
methods are also available.
Here is an example function from the ``sed`` recipe::
do_install () {
autotools_do_install
install -d ${D}${base_bindir}
mv ${D}${bindir}/sed ${D}${base_bindir}/sed
rmdir ${D}${bindir}/
}
It is
also possible to implement new functions that are called between
existing tasks as long as the new functions are not replacing or
complementing the default functions. You can implement functions in
Python instead of shell. Both of these options are not seen in the
majority of recipes.
- *Keywords:* BitBake recipes use only a few keywords. You use keywords
to include common functions (``inherit``), load parts of a recipe
from other files (``include`` and ``require``) and export variables
to the environment (``export``).
The following example shows the use of some of these keywords::
export POSTCONF = "${STAGING_BINDIR}/postconf"
inherit autoconf
require otherfile.inc
- *Comments (#):* Any lines that begin with the hash character (``#``)
are treated as comment lines and are ignored::
# This is a comment
This next list summarizes the most important and most commonly used
parts of the recipe syntax. For more information on these parts of the
syntax, you can reference the
":doc:`bitbake:bitbake-user-manual/bitbake-user-manual-metadata`" chapter
in the BitBake User Manual.
- *Line Continuation (\\):* Use the backward slash (``\``) character to
split a statement over multiple lines. Place the slash character at
the end of the line that is to be continued on the next line::
VAR = "A really long \
line"
.. note::
You cannot have any characters including spaces or tabs after the
slash character.
- *Using Variables (${VARNAME}):* Use the ``${VARNAME}`` syntax to
access the contents of a variable::
SRC_URI = "${SOURCEFORGE_MIRROR}/libpng/zlib-${PV}.tar.gz"
.. note::
It is important to understand that the value of a variable
expressed in this form does not get substituted automatically. The
expansion of these expressions happens on-demand later (e.g.
usually when a function that makes reference to the variable
executes). This behavior ensures that the values are most
appropriate for the context in which they are finally used. On the
rare occasion that you do need the variable expression to be
expanded immediately, you can use the
:=
operator instead of
=
when you make the assignment, but this is not generally needed.
- *Quote All Assignments ("value"):* Use double quotes around values in
all variable assignments (e.g. ``"value"``). Following is an example::
VAR1 = "${OTHERVAR}"
VAR2 = "The version is ${PV}"
- *Conditional Assignment (?=):* Conditional assignment is used to
assign a value to a variable, but only when the variable is currently
unset. Use the question mark followed by the equal sign (``?=``) to
make a "soft" assignment used for conditional assignment. Typically,
"soft" assignments are used in the ``local.conf`` file for variables
that are allowed to come through from the external environment.
Here is an example where ``VAR1`` is set to "New value" if it is
currently empty. However, if ``VAR1`` has already been set, it
remains unchanged::
VAR1 ?= "New value"
In this next example, ``VAR1`` is left with the value "Original value"::
VAR1 = "Original value"
VAR1 ?= "New value"
- *Appending (+=):* Use the plus character followed by the equals sign
(``+=``) to append values to existing variables.
.. note::
This operator adds a space between the existing content of the
variable and the new content.
Here is an example::
SRC_URI += "file://fix-makefile.patch"
- *Prepending (=+):* Use the equals sign followed by the plus character
(``=+``) to prepend values to existing variables.
.. note::
This operator adds a space between the new content and the
existing content of the variable.
Here is an example::
VAR =+ "Starts"
- *Appending (:append):* Use the ``:append`` operator to append values
to existing variables. This operator does not add any additional
space. Also, the operator is applied after all the ``+=``, and ``=+``
operators have been applied and after all ``=`` assignments have
occurred. This means that if ``:append`` is used in a recipe, it can
only be overridden by another layer using the special ``:remove``
operator, which in turn will prevent further layers from adding it back.
The following example shows the space being explicitly added to the
start to ensure the appended value is not merged with the existing
value::
CFLAGS:append = " --enable-important-feature"
You can also use
the ``:append`` operator with overrides, which results in the actions
only being performed for the specified target or machine::
CFLAGS:append:sh4 = " --enable-important-sh4-specific-feature"
- *Prepending (:prepend):* Use the ``:prepend`` operator to prepend
values to existing variables. This operator does not add any
additional space. Also, the operator is applied after all the ``+=``,
and ``=+`` operators have been applied and after all ``=``
assignments have occurred.
The following example shows the space being explicitly added to the
end to ensure the prepended value is not merged with the existing
value::
CFLAGS:prepend = "-I${S}/myincludes "
You can also use the
``:prepend`` operator with overrides, which results in the actions
only being performed for the specified target or machine::
CFLAGS:prepend:sh4 = "-I${S}/myincludes "
- *Overrides:* You can use overrides to set a value conditionally,
typically based on how the recipe is being built. For example, to set
the :term:`KBRANCH` variable's
value to "standard/base" for any target
:term:`MACHINE`, except for
qemuarm where it should be set to "standard/arm-versatile-926ejs",
you would do the following::
KBRANCH = "standard/base"
KBRANCH:qemuarm = "standard/arm-versatile-926ejs"
Overrides are also used to separate
alternate values of a variable in other situations. For example, when
setting variables such as
:term:`FILES` and
:term:`RDEPENDS` that are
specific to individual packages produced by a recipe, you should
always use an override that specifies the name of the package.
- *Indentation:* Use spaces for indentation rather than tabs. For
shell functions, both currently work. However, it is a policy
decision of the Yocto Project to use tabs in shell functions. Realize
that some layers have a policy to use spaces for all indentation.
- *Using Python for Complex Operations:* For more advanced processing,
it is possible to use Python code during variable assignments (e.g.
search and replacement on a variable).
You indicate Python code using the ``${@python_code}`` syntax for the
variable assignment::
SRC_URI = "ftp://ftp.info-zip.org/pub/infozip/src/zip${@d.getVar('PV',1).replace('.', '')}.tgz
- *Shell Function Syntax:* Write shell functions as if you were writing
a shell script when you describe a list of actions to take. You
should ensure that your script works with a generic ``sh`` and that
it does not require any ``bash`` or other shell-specific
functionality. The same considerations apply to various system
utilities (e.g. ``sed``, ``grep``, ``awk``, and so forth) that you
might wish to use. If in doubt, you should check with multiple
implementations --- including those from BusyBox.
|