aboutsummaryrefslogtreecommitdiffstats
path: root/usermanual/chapters/recipes.xml
blob: a54c4f833cfc13a31994fbea1f91648ae8b18d41 (plain)
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
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
<?xml version="1.0" encoding="UTF-8"?>
<chapter>
  <title>Recipes</title>

  <section id="bb_introduction" xreflabel="introduction">
    <title>Introduction</title>

    <para>A bitbake recipe is a set of instructions that describe what needs
    to be done to retrieve the source code for some application, apply any
    necessary patches, provide any additional files (such as init scripts),
    compile it, install it and generated binary packages. The end result is a
    binary package that you can install on your target device, and maybe some
    intermediate files, such as libraries and headers, which can be used when
    building other application.</para>

    <para>In many ways the process is similar to creating .deb or .rpm
    packages for your standard desktop distributions with one major difference
    - in OpenEmbedded everything is being cross-compiled. This often makes the
    task far more difficult (depending on how well suited the application is
    to cross compiling), then it is for other packaging systems and sometime
    impossible.</para>

    <para>This chapter assumes that you are familiar with working with
    bitbake, including the work flow, required directory structures, bitbake
    configuration and the use of monotone. If you are not familiar with these
    then first take a look at the chapter on bitbake usage.</para>
  </section>

  <section id="bb_syntax" xreflabel="syntax">
    <title>Syntax of recipes</title>

    <para>The basic items that make up a bitbake recipe file are:</para>

    <variablelist>
      <varlistentry>
        <term>functions</term>

        <listitem>
          <para>Functions provide a series of actions to be performed.
          Functions are usually used to override the default implementation of
          a task function, or to compliment (append or prepend to an existing
          function) a default function. Standard functions use sh shell
          syntax, although access to OpenEmbedded variables and internal
          methods is also available.</para>

          <para>The following is an example function from the sed
          recipe:</para>

          <para><screen>do_install () {
    autotools_do_install
    install -d ${D}${base_bindir}
    mv ${D}${bindir}/sed ${D}${base_bindir}/sed.${PN}
}</screen>It is also possible to implement new functions, that are not
          replacing or complimenting the default functions, which are called
          between existing tasks. It is also possible to implement functions
          in python instead of sh. Both of these options are not seen in the
          majority of recipes.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>variable assignments and manipulations</term>

        <listitem>
          <para>Variable assignments allow a value to be assigned to a
          variable. The assignment may be static text or might include the
          contents of other variables. In addition to assignment, appending
          and prepending operations are also supported.</para>

          <para>The follow example shows the some of the ways variables can be
          used in recipes:<screen>S = "${WORKDIR}/postfix-${PV}"
PR = "r4"
CFLAGS += "-DNO_ASM"
SRC_URI_append = "file://fixup.patch;patch=1"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>keywords</term>

        <listitem>
          <para>Only a few keywords are used in bitbake recipes. They are used
          for things such as including common functions
          (<emphasis>inherit</emphasis>), loading parts of a recipe from other
          files (<emphasis>include</emphasis> and
          <emphasis>require</emphasis>) and exporting variables to the
          environment (export).</para>

          <para>The following example shows the use of some of these
          keywords:<screen>export POSTCONF = "${STAGING_BINDIR}/postconf"
inherit autoconf
require otherfile.inc</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>comments</term>

        <listitem>
          <para>Any lines that begin with a # are treated as comment lines and
          are ignored.<screen># This is a comment</screen></para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>The following is a summary of the most important (and most commonly
    used) parts of the recipe syntax:</para>

    <variablelist>
      <varlistentry>
        <term>Line continuation: \</term>

        <listitem>
          <para>To split a line over multiple lines you should place a \ at
          the end of the line that is to be continued on the next line.</para>

          <screen>VAR = "A really long \
       line"</screen>

          <para>Note that there must not be anything (no spaces or tabs) after
          the \.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Comments: #</term>

        <listitem>
          <para>Any lines beginning with a # are comments and will be
          ignored.<screen># This is a comment</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Using variables: ${...}</term>

        <listitem>
          <para>To access the contents of a variable you need to access it via
          <emphasis>${&lt;varname&gt;}</emphasis>:<screen>SRC_URI = "${SOURCEFORGE_MIRROR}/libpng/zlib-${PV}.tar.gz"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Quote all assignments</term>

        <listitem>
          <para>All variable assignments should be quoted with double quotes.
          (It may work without them at present, but it will not work in the
          future).<screen>VAR1 = "${OTHERVAR}"
VAR2 = "The version is ${PV}"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Appending: +=</term>

        <listitem>
          <para>You can append values to existing variables using the
          <emphasis>+=</emphasis> operator. Note that this operator will add a
          space between the existing content of the variable and the new
          content.<screen>SRC_URI += "file://fix-makefile.patch;patch=1"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Prepending: =+</term>

        <listitem>
          <para>You can prepend values to existing variables using the
          <emphasis>=+</emphasis> operator. Note that this operator will add a
          space between the new content and the existing content of the
          variable.<screen>VAR =+ "Starts"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Appending: _append</term>

        <listitem>
          <para>You can append values to existing variables using the
          <emphasis>_append</emphasis> method. Note that this operator does
          not add any additional space, and it is applied after all the
          <emphasis>+=</emphasis>, and <emphasis>=+</emphasis> operators have
          been applied.</para>

          <para>The following example show the space being explicitly added to
          the start to ensure the appended value is not merged with the
          existing value:<screen>SRC_URI_append = " file://fix-makefile.patch;patch=1"</screen>The
          <emphasis>_append</emphasis> method can also be used with overrides,
          which result in the actions only being performed for the specified
          target or machine: [TODO: Link to section on overrides]<screen>SRC_URI_append_sh4 = " file://fix-makefile.patch;patch=1"</screen>Note
          that the appended information is a variable itself, and therefore
          it's possible to used <emphasis>+=</emphasis> or
          <emphasis>=+</emphasis> to assign variables to the
          <emphasis>_append</emphasis> information:<screen>SRC_URI_append = " file://fix-makefile.patch;patch=1"
SRC_URI_append += "file://fix-install.patch;patch=1"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Prepending: _prepend</term>

        <listitem>
          <para>You can prepend values to existing variables using the
          _prepend method. Note that this operator does not add any additional
          space, and it is applied after all the <emphasis>+=</emphasis>, and
          <emphasis>=+</emphasis> operators have been applied.</para>

          <para>The following example show the space being explicitly added to
          the end to ensure the prepended value is not merged with the
          existing value:<screen>CFLAGS_prepend = "-I${S}/myincludes "</screen>The
          <emphasis>_prepend</emphasis> method can also be used with
          overrides, which result in the actions only being performed for the
          specified target or machine: [TODO: Link to section on
          overrides]<screen>CFLAGS_prepend_sh4 = " file://fix-makefile.patch;patch=1"</screen>Note
          that the appended information is a variable itself, and therefore
          it's possible to used <emphasis>+=</emphasis> or
          <emphasis>=+</emphasis> to assign variables to the
          <emphasis>_prepend</emphasis> information:<screen>CFLAGS_prepend = "-I${S}/myincludes "
CFLAGS_prepend += "-I${S}/myincludes2 "</screen>Note also the lack of a space
          when using += to append to a prepend value - remember that the +=
          operator is adding space itself.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Spaces vs tabs</term>

        <listitem>
          <para>Spaces should be used for indentation, not hard tabs. Both
          currently work, however it is a policy decision of OE that spaces
          always be used.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Style: oe-stylize.py</term>

        <listitem>
          <para>To help with using the correct style in your recipes there is
          a python script in the contrib directory called
          <emphasis>oe-stylize.py</emphasis> which can be used to reformat
          your recipes to the correct style. The output will contain a list of
          warning (to let you know what you did wrong) which should be edited
          out before using the new file.<screen>contrib/oe-stylize.py myrecipe.bb &gt; fixed-recipe.bb
vi fixed-recipe.bb
mv fixed.recipe.bb myrecipe.bb</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Using python for complex operations: ${@...}</term>

        <listitem>
          <para>For more advanced processing it is possible to use python code
          during variable assignments, for doing search and replace on a
          variable for example.</para>

          <para>Python code is indicated by a proceeding @ sign in the
          variable assignment.<screen>CXXFLAGS := "${@'${CXXFLAGS}'.replace('-frename-registers', '')}"</screen>More
          information about using python is available in the <xref
          linkend="bb_advanced_python" /> section.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Shell syntax</term>

        <listitem>
          <para>When describing a list of actions to take shell syntax is used
          (as if you were writing a shell script). You should ensure that you
          script would work with a generic sh and not require any bash (or
          other shell) specific functionality. The same applies to various
          system utilities (sed, grep, awk etc) that you may wish to use. If
          in doubt you should check with multiple implementations - including
          those from busybox.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>For a detailed description of the syntax for the bitbake recipe
    files you should refer to the bitbake use manual.</para>
  </section>

  <section id="bb_versioning" xreflabel="versioning">
    <title>Recipe naming: Names, versions and releases</title>

    <para>Recipes in OpenEmbedded use a standard naming convention that
    includes the package name and version number in the filename. In addition
    to the name and version there is also a release number, which is indicates
    changes to the way the package is built and/or packaged. The release
    number is contained within the recipe itself.</para>

    <para>The expected format of recipe name is:<screen>&lt;package-name&gt;_&lt;version&gt;.bb</screen></para>

    <para>where <emphasis>&lt;package-name&gt;</emphasis> is the name of the
    package (application, library, module, or whatever it is that is being
    packaged) and <emphasis>version</emphasis> is the version number.</para>

    <para>So a typical recipe name would be:<screen>strace_4.5.14.bb</screen>which
    would be for version <emphasis>4.5.14</emphasis> of the
    <emphasis>strace</emphasis> application.</para>

    <para>The release version is defined via the package release variable, PR,
    contained in the recipe. The expected format is:<screen>r&lt;n&gt;</screen>where
    <emphasis>&lt;n&gt;</emphasis> is an integer number starting from 0
    initially and then incremented each time the recipe, or something that
    effects the recipe, is modified. So a typical definition of the release
    would be:<screen>PR = "r1"</screen>to specify release number
    <emphasis>1</emphasis> (the second release, the first would have been
    <emphasis>0</emphasis>). If there is no definition of PR in the recipe
    then the default value of "r0" is used.</para>

    <para><note>
        <para>It is good practice to always define PR in your recipes, even
        for the <emphasis>"r0"</emphasis> release, so that when editing the
        recipe it is clear that the PR number needs to be updated.</para>
      </note></para>

    <para>When a recipe is being processed some variables are automatically
    set based on the recipe file name and can be used for other purposes from
    within the recipe itself. These include:</para>

    <variablelist>
      <varlistentry>
        <term>PN</term>

        <listitem>
          <para>The package name. Determined from the recipe filename -
          everything up until the first underscore is considered to be the
          package name. For the <command>strace_4.5.14.bb</command> recipe the
          PN variable would be set to <emphasis>"strace"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PV</term>

        <listitem>
          <para>The package version. Determined from the recipe filename -
          everything between the first underscore and the final .bb is
          considered to be the package version. For the
          <command>strace_4.5.14.bb</command> recipe the PV variable would be
          set to <emphasis>"4.5.14"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PR</term>

        <listitem>
          <para>The package release. This is explicitly set in the recipe, or
          if not set it defaults to "<emphasis>r0"</emphasis> if not
          set.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>P</term>

        <listitem>
          <para>The package name and versions separated by a hyphen.<screen>P = "${PN}-${PV}"</screen></para>

          <para>For the <command>strace_4.5.14.bb</command> recipe the P
          variable would be set to
          <emphasis>"strace-4.5.14"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PF</term>

        <listitem>
          <para>The package name, version and release separated by
          hyphens.<screen>PF = "${PN}-${PV}-${PR}"</screen></para>

          <para>For the s<command>trace_4.5.14.bb recipe</command>, with PR
          set to <emphasis>"r1"</emphasis> in the recipe, the PF variable
          would be set to <emphasis>"strace-4.5.14-r1"</emphasis>.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>While some of these variables are not commonly used in recipes (they
    are used internally though) both PN and PV are used a lot.</para>

    <para>In the following example we are instructing the packaging system to
    include an additional directory in the package. We use PN to refer to the
    name of the package rather than spelling out the package name:<screen>FILES_${PN} += "${sysconfdir}/myconf"</screen></para>

    <para>In the next example we are specifying the URL for the package
    source, by using PV in place of the actual version number it is possible
    to duplicate, or rename, the recipe for a new version without having to
    edit the URL:<screen>SRC_URI = "ftp://ftp.vim.org/pub/vim/unix/vim-${PV}.tar.bz2"</screen></para>

    <para></para>
  </section>

  <section id="bb_variables" xreflabel="variables">
    <title>Variables</title>

    <para>One of the most confusing part of bitbake recipes for new users is
    the large amount of variables that appear to be available to change and/or
    control the behaviour of some aspect of the recipe. Some variables, such
    as those derived from the file name are reasonably obvious, others are not
    at all obvious.</para>

    <para>There are several places where these variables are derived from
    and/or used:</para>

    <orderedlist>
      <listitem>
        <para>A large number of variables are defined in the bitbake
        configuration file conf/bitbake.conf - it's often a good idea to look
        through that file when trying to determine what a particular variable
        means.</para>
      </listitem>

      <listitem>
        <para>Machine and distribution configuration files in conf/machine and
        conf/distro will sometimes define some variables specific to the
        machine and/or distribution. You should look at the appropriate files
        for your targets to see if anything is being defined that effects the
        recipes you are building.</para>
      </listitem>

      <listitem>
        <para>Bitbake itself will define some variables. The FILE variables
        that defines the name of the bitbake recipe being processed is set by
        bitbake itself for example. Refer to the bitbake manual for more
        information on the variables that bitbake sets.</para>
      </listitem>

      <listitem>
        <para>The classes, that are used via the inherit keyword, define
        and/or use the majority of the remaining variables. A class is a like
        a library that contain parts of a bitbake recipe that are used by
        multiple recipes. To make them usable in more situations they often
        include a large number of variables to control how the class
        operates.</para>
      </listitem>
    </orderedlist>

    <para>Another important aspect is that there are three different types of
    things that binaries and libraries are used for and they often have
    different variables for each. These include:</para>

    <variablelist>
      <varlistentry>
        <term>target</term>

        <listitem>
          <para>Refers to things built for the target are expected to be run
          on the target device itself.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>native</term>

        <listitem>
          <para>Refers to things built to run natively on the build host
          itself.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>cross</term>

        <listitem>
          <para>Refers to things built to run natively on the build host
          itself, but produce output which is suitable for the target device.
          Cross versions of packages usually only exist for things like
          compilers and assemblers - i.e. things which are used to produce
          binary applications themselves.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para></para>
  </section>

  <section id="bb_header" xreflabel="header">
    <title>Header</title>

    <para>Practically all recipes start was the header section which describes
    various aspects of the package that is being built. This information is
    typically used directly by the package format (such as ipkg or deb) as
    it's meta data used to describe the package.</para>

    <para>Variables used in the header include:</para>

    <variablelist>
      <varlistentry>
        <term>DESCRIPTION</term>

        <listitem>
          <para>Describes what the software does. Hopefully this gives enough
          information to a use to know if it's the right application for
          them.</para>

          <para>The default description is: <emphasis>"Version ${PV}-${PR} of
          package ${PN}"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>HOMEPAGE</term>

        <listitem>
          <para>The URL of the home page of the application where new releases
          and more information can be found.</para>

          <para>The default homepage is <emphasis>"unknown"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>SECTION</term>

        <listitem>
          <para>The section is used to categorise the application into a
          specific group. Often used by GUI based installers to help users
          when searching for software.</para>

          <para>See <xref linkend="section_variable" /> for a list of the
          available sections.</para>

          <para>The default section is <emphasis>"base"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PRIORITY</term>

        <listitem>
          <para>The default priority is
          <emphasis>"optional"</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>LICENSE</term>

        <listitem>
          <para>The license for the application. If it is not one of the
          standard licenses then the license itself must be included
          (where?).</para>

          <para>As well as being used in the package meta-data the license is
          also used by the src_distribute class.</para>

          <para>The default license is <emphasis>"unknown"</emphasis>.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para></para>
  </section>

  <section id="bb_structure" xreflabel="structure">
    <title>Structure</title>

    <para>talk about about what directories and files are involved - using
    bitbake stuff would cover this in detail, just short summary here</para>
  </section>

  <section id="bb_sources" xreflabel="sources">
    <title>Sources: Downloading, patching and additional files</title>

    <para>A recipes purpose is to describe how to take a software package and
    build it for your target device. The location of the source file (or
    files) is specified via the <xref linkend="src_uri_variable" /> in the
    recipe. This can describe several types of URI's, the most common
    are:</para>

    <variablelist>
      <varlistentry>
        <term>http and https</term>

        <listitem>
          <para>Specifies files to be downloaded. A copy is stored locally so
          that future builds will not download the source again.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>cvs, svn and git</term>

        <listitem>
          <para>Specifies that the files are to be retrieved using the
          specified version control system.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>files</term>

        <listitem>
          <para>Plain files which are included locally. These can be used for
          adding documentation, init scripts or any other files that need to
          be added to build the package under openembedded.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>patches</term>

        <listitem>
          <para>Patches are plain files which are treated as patched and
          automatically applied.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>If a http, https or file URI refers to a compressed file, an archive
    file or a compressed archive file, such as .tar.gz or .zip, then the files
    will be uncompressed and extracted from the archive automatically.</para>

    <para>Archive files will be extracted from with the working directory,
    <emphasis role="bold">${WORKDIR}</emphasis> and plain files will be copied
    into the same directory. Patches will be applied from within the unpacked
    source directory, <emphasis role="bold">${S}</emphasis>. (Details on these
    directories is provided in the next section.)</para>

    <para>The following example from the havp recipe shows a typical <emphasis
    role="bold">SRC_URI</emphasis> definition:<screen>SRC_URI = "http://www.server-side.de/download/havp-${PV}.tar.gz \
           file://sysconfdir-is-etc.patch;patch=1 \
           file://havp.init \
           file://doc.configure.txt \
           file://volatiles.05_havp"</screen></para>

    <para>This describes several files</para>

    <variablelist>
      <varlistentry>
        <term>http://www.server-side.de/download/havp-${PV}.tar.gz</term>

        <listitem>
          <para>This is the URI of the havp source code. Note the use of the
          <emphasis role="bold">${PV}</emphasis> variable to specify the
          version. This is done to enable the recipe to be renamed for a new
          version without the need the edit the recipe itself. Because this is
          a .tar.gz compressed archive the file will be decompressed and
          extracted in the working dir <emphasis
          role="bold">${WORKDIR}</emphasis>.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>file://sysconfdir-is-etc.patch;patch=1</term>

        <listitem>
          <para>This is a local file that is used to patch the extracted
          source code. The patch=1 is what specifies that this is a patch. The
          patch will be applied from the unpacked source directory, <emphasis
          role="bold">${S}</emphasis>. In this case <emphasis
          role="bold">${S}</emphasis> will be <emphasis
          role="bold">${WORKDIR}/havp-0.82</emphasis>, and luckily the
          <emphasis role="bold">havp-0.82.tar.gz</emphasis> file extracts
          itself into that directory (so no need to explicitly change
          <emphasis role="bold">${S}</emphasis>).</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>file://havp.init file://doc.configure.txt
        file://volatiles.05_havp"</term>

        <listitem>
          <para>These are plain files which are just copied into the working
          directory <emphasis role="bold">${WORKDIR}</emphasis>. These are
          then used during the install task in the recipe to provide init
          scripts, documentation and volatiles configuration information for
          the package.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Full details on the <emphasis role="bold">SRC_URI</emphasis>
    variable and all the support URI's is available in the <xref
    linkend="src_uri_variable" /> section of the reference chapter.</para>
  </section>

  <section id="bb_directories" xreflabel="directories">
    <title>Directories: What goes where</title>

    <para>target directories</para>

    <para>unpacked source directory</para>

    <para>work directory</para>

    <para>files/filespath</para>

    <para>staging directories</para>

    <para>install directories</para>

    <para></para>

    <section>
      <title>WORKDIR: The working directory</title>

      <para>The working directory is where the source code is extracted, to
      which plain files (not patches) are copied and where the logs and
      installation files are created. A typical reason for needing to
      reference the work directory is for the handling of non patch
      files.</para>

      <para>If we take a look at the recipe for quagga we can see an example
      non patch files for configuration and init scripts:<screen>SRC_URI = "http://www.quagga.net/download/quagga-${PV}.tar.gz \
           file://fix-for-lib-inpath.patch;patch=1 \
           file://quagga.init \
           file://quagga.default \
           file://watchquagga.init \
           file://watchquagga.default"</screen>The recipe has two init files
      and two configuration files, which are not patches, but are actually
      files that it wants to include in the generated packages. Bitbake will
      copy these files into the work directory. So to access them during the
      install task we refer to them via the <emphasis
      role="bold">WORKDIR</emphasis> variable:<screen>do_install () {
    # Install init script and default settings
    install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga
    install -m 0644 ${WORKDIR}/quagga.default ${D}${sysconfdir}/default/quagga
    install -m 0644 ${WORKDIR}/watchquagga.default ${D}${sysconfdir}/default/watchquagga
    install -m 0755 ${WORKDIR}/quagga.init ${D}${sysconfdir}/init.d/quagga
    install -m 0755 ${WORKDIR}/watchquagga.init ${D}${sysconfdir}/init.d/watchquagga
    ...</screen></para>

      <para></para>
    </section>

    <section>
      <title>S: The unpacked source code directory</title>

      <para>Bitbake expects to find the extracted source for a package in a
      directory called <emphasis
      role="bold">&lt;packagename&gt;-&lt;version&gt;</emphasis> in the
      <emphasis role="bold">WORKDIR</emphasis> directory. This is the
      directory in which it will change into before patching, compiling and
      installation the package.</para>

      <para>For example, we have a package called <emphasis
      role="bold">widgets_1.2.bb</emphasis> which we are extracting from the
      <emphasis role="bold">widgets-1.2.tar.gz</emphasis> file. Bitbake
      expects the source to end up in a directory called <emphasis
      role="bold">widgets-1.2</emphasis> within the work directory. If the
      source does not end up in this directory then bitbake needs to be told
      this by explicitly setting <emphasis role="bold">S</emphasis>.</para>

      <para>If <emphasis role="bold">widgets-1.2.tar.gz</emphasis> actually
      extracts into a directory called <emphasis
      role="bold">widgets</emphasis>, without the version number, instead of
      <emphasis role="bold">widgets-1.2</emphasis> then the <emphasis
      role="bold">S</emphasis> variable will be wrong and patching and/or
      compiling will fail. Therefore we need to override the default value of
      <emphasis role="bold">S</emphasis> to specify the directory the source
      was actually extracted into:<screen>SRC_URI = "http://www.example.com/software/widgets-${PN}.tar.gz"
S = "${WORKDIR}/widgets"</screen></para>

      <para></para>
    </section>

    <section>
      <title>D: The destination directory</title>

      <para>The destination directory is where the completed application and
      all of it's files are installed into in preparation for packaging.
      Typically an installation would places files in directories such as
      <emphasis role="bold">/etc</emphasis> and <emphasis
      role="bold">/usr/bin</emphasis> by default. Since those directories are
      used by the host system we do not want the packages to install into
      those locations. Instead they need to install into the directories below
      the destination directory.</para>

      <para>So instead of installing into <emphasis
      role="bold">/usr/bin</emphasis> the package needs to install into
      <emphasis role="bold">${D}/usr/bin</emphasis>.</para>

      <para>The following example from arpwatch shows the make install command
      being passed a <emphasis role="bold">${D}</emphasis> as the <emphasis
      role="bold">DESTDIR</emphasis> variable to control where the makefile
      installs everything:<screen>do_install() {
        ...
        oe_runmake install DESTDIR=${D}</screen></para>

      <para>The following example from quagga shows the use of the destination
      directory to install the configuration files and init scripts for the
      package:<screen>do_install () {
        # Install init script and default settings
        install -m 0755 -d ${D}${sysconfdir}/default ${D}${sysconfdir}/init.d ${D}${sysconfdir}/quagga
        install -m 0644 ${WORKDIR}/quagga.default ${D}${sysconfdir}/default/quagga
        install -m 0755 ${WORKDIR}/quagga.init ${D}${sysconfdir}/init.d/quagga</screen><note>
          <para>You should not use directories such as <emphasis
          role="bold">/etc</emphasis> and <emphasis
          role="bold">/usr/bin</emphasis> directly in your recipes. You should
          use the variables that define these locations. The full list of
          these variables can be found in the <xref
          linkend="directories_installation" /> section of the reference
          chapter.</para>
        </note></para>
    </section>

    <section>
      <title>Staging directories</title>

      <para>Staging is used to make libraries, headers and binaries available
      for the build of one recipe for use by another recipe. Building a
      library for example requires that packages be created containing the
      libraries and headers for development on the target as well as making
      them available on the host for building other packages that need the
      libraries and headers.</para>

      <para>Making the libraries, headers and binaries available for use by
      other recipes on the host is called staging and is performed by the
      <emphasis>stage</emphasis> task in the recipe. Any recipes that contain
      items that are required to build other packages should have a
      <emphasis>stage</emphasis> task to make sure the items are all correctly
      placed into the staging area. The following example from clamav show the
      clamav library and header being placed into the staging area:<screen>do_stage () {
        oe_libinstall -a -so libclamav ${STAGING_LIBDIR}
        install -m 0644 libclamav/clamav.h ${STAGING_INCDIR}
}</screen></para>

      <para>The following from the p3scan recipe show the path to the clamav
      library and header being passed to the configure script. Without this
      the configure script would either fail to find the library, or worse
      still search the host systems directories for the library. Passing in
      the location results in it searching the correct location and finding
      the clamav library and headers:<screen>EXTRA_OECONF = "--with-clamav=${STAGING_LIBDIR}/.. \
                --with-openssl=${STAGING_LIBDIR}/.. \
                --disable-ripmime"</screen>While the staging directories are
      automatically added by OpenEmbedded to the compiler and linking commands
      it is sometimes necessary, as in the p3scan example above, to explicitly
      specify the location of the staging directories. Typically this is
      needed for autoconf scripts that search in multiple places for the
      libraries and headers.</para>

      <note>
        <para>Many of the helper classes, such as pkgconfig and autotools add
        appropriate commands to the stage task for you. Check with the
        individual class descriptions in the reference section to determine
        what each class is staging automatically for you.</para>
      </note>

      <para>A full list of staging directories can be found in the <xref
      linkend="directories_staging" /> section in the reference
      chapter.</para>
    </section>

    <section>
      <title>FILESPATH/FILESDIR: Finding local files</title>

      <para>The file related variables are used by bitbake to determine where
      to look for patches and local files.</para>

      <para>Typically you will not need to modify these, but it is useful to
      be aware of the default values. In particular when searching for patches
      and/or files (file:// URI's), the default search path is:</para>

      <variablelist>
        <varlistentry>
          <term>${FILE_DIRNAME}/${PF}</term>

          <listitem>
            <para>This is the package name, version and release, such as
            "<emphasis role="bold">strace-4.5.14-r1</emphasis>". This is very
            rarely used since the patches would only be found for the one
            exact release of the recipe.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/${P}</term>

          <listitem>
            <para>This is the package name and version, such as "<emphasis
            role="bold">strace-4.5.14</emphasis>". This is by far the most
            common place to place version specified patches.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/${PN}</term>

          <listitem>
            <para>This is the package name only, such as "<emphasis
            role="bold">strace</emphasis>". This is not commonly used.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/files</term>

          <listitem>
            <para>This is just the directory called "<emphasis
            role="bold">files</emphasis>". This is commonly used for patches
            and files that apply to all version of the package.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>${FILE_DIRNAME}/</term>

          <listitem>
            <para>This is just the base directory of the recipe. This is very
            rarely used since it would just clutter the main directory.</para>
          </listitem>
        </varlistentry>
      </variablelist>

      <para>Each of the paths is relative to <emphasis
      role="bold">${FILE_DIRNAME}</emphasis> which is the directory in which
      the recipe that is being processed is located.</para>

      <para>The full set of variables that control the file locations and
      patch are:</para>

      <variablelist>
        <varlistentry>
          <term>FILE</term>

          <listitem>
            <para>The path to the .bb file which is currently being
            processed.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>FILE_DIRNAME</term>

          <listitem>
            <para>The path to the directory which contains the FILE which is
            currently being processed.<screen>FILE_DIRNAME = "${@os.path.dirname(bb.data.getVar('FILE', d))}"</screen></para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>FILESPATH</term>

          <listitem>
            <para>The default set of directories which are available to use
            for the file:// URI's. Each directory is searched, in the
            specified order, in an attempt to find the file specified by each
            file:// URI: <screen>FILESPATH = "${FILE_DIRNAME}/${PF}:${FILE_DIRNAME}/${P}:\
${FILE_DIRNAME}/${PN}:${FILE_DIRNAME}/files:${FILE_DIRNAME}"</screen></para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>FILESDIR</term>

          <listitem>
            <para>The default directory to search for file:// URI's. Only used
            if the file is not found in FILESPATH. This can be used to easily
            add one additional directory to the search path without having to
            modify the default FILESPATH setting. By default this is just the
            first directory from FILESPATH. <screen>FILESDIR = "${@bb.which(bb.data.getVar('FILESPATH', d, 1), '.')}" </screen></para>
          </listitem>
        </varlistentry>
      </variablelist>

      <para>Sometimes recipes will modify the <emphasis
      role="bold">FILESPATH</emphasis> or <emphasis
      role="bold">FILESDIR</emphasis> variables to change the default search
      path for patches and files. The most common situation in which this is
      done is when one recipe includes another one in which the default values
      will be based on the name of the package doing the including, not the
      included package. Typically the included package will expect the files
      to be located in a directories based on it's own name.</para>

      <para>As an example the m4-native recipe includes the m4 recipe. This is
      fine, except that the m4 recipes expects its files and patches to be
      located in a directory called <emphasis role="bold">m4</emphasis>
      directory while the native file name results in them being searched for
      in <emphasis role="bold">m4-native</emphasis>. So the m4-native recipe
      sets the <emphasis role="bold">FILESDIR</emphasis> variable to the value
      that of m4 to add the actual m4 directory (where m4 itself has its files
      stored) to the list of directories search for:<screen>        include m4_${PV}.bb
        inherit native
        FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/m4"</screen></para>
    </section>
  </section>

  <section id="bb_examples" xreflabel="examples">
    <title>Basic examples</title>

    <para>By now you should know enough about the bitbake recipes to be able
    to create a basic recipe. We'll cover a simple single file recipe and then
    a more advanced example that uses the autotools helper class (to be
    described later) to build an autoconf based package.</para>

    <section id="bb_helloworld_example" xreflabel="hello world example">
      <title>Hello world</title>

      <para>Now it's time for our first recipe. This is going to be one of the
      simplest possible recipes: all code is included and there's only one
      file to compile and one readme file. While this isn't all that common
      it's a useful example because it doesn't depend on any of the helper
      classes which can sometime hide a lot of what is going on.</para>

      <para>First we'll create the helloworld.c file and a readme file. We'll
      place this in the files subdirectory, which is one of the places that is
      searched for file:// URI's:<screen>mkdir packages/helloworld
mkdir pacakges/helloworld/files
cat &gt; pacakges/helloworld/files/helloworld.c
#include &lt;stdio.h&gt;

int main(int argc, char** argv)
{
        printf("Hello world!\n");
        return 0;
}
^D
cat &gt; pacakges/helloworld/files/README.txt
Readme file for helloworld.
^D</screen></para>

      <para>Now we have a directory for our recipe, packages/helloworld, and
      we've created a files subdirectory in there to store our local files.
      We've created two local files, the C source code for our helloworld
      program and a readme file. Now we need to create the bitbake
      recipe.</para>

      <para>First we need the header section, which will contain a description
      of the package and the release number. We'll leave the other header
      variables out for now:<screen>DESCRIPTION = "Hello world program"
PR = "r0"</screen></para>

      <para>Next we need to tell it which files we want to be included in the
      recipe, which we do via file:// URI's and the SRC_URI variable:<screen>SRC_URI = "file://helloworld.c \
           file://README.txt"</screen></para>

      <para>Note the use of the \ to continue a file and the file of file://
      local URI's, rather than other types such as http://.</para>

      <para>Now we need provide a compile task which tells bitbake how to
      compile this program. We do this by defining a do_compile function in
      the recipe and providing the appropriate commands:</para>

      <para><screen>do_compile() {
        ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/helloworld.c -o helloworld
}</screen></para>

      <para>Note the:</para>

      <itemizedlist>
        <listitem>
          <para>use of the pre-defined compiler variables, <emphasis
          role="bold">${CC}</emphasis>, <emphasis
          role="bold">${CFLAGS}</emphasis> and <emphasis
          role="bold">${LDFLAGS}</emphasis>. These are setup automatically to
          contain the settings required to cross-compile the program for the
          target.</para>
        </listitem>

        <listitem>
          <para>use of <emphasis role="bold">${WORKDIR}</emphasis> to find the
          source file. As mentioned previously all files are copied into the
          working directory and can be referenced via the <emphasis
          role="bold">${WORKDIR}</emphasis> variable.</para>
        </listitem>
      </itemizedlist>

      <para>And finally we want to install the program and readme file into
      the destination directory so that it'll be packaged up correctly. This
      is done via the install task, so we need to define a do_install function
      in the recipe to describe how to install the package:<screen>do_install() {
        install -m 0755 -d ${D}${bindir} ${D}${docdir}/helloworld
        install -m 0644 ${S}/helloworld ${D}${bindir}
        install -m 0644 ${WORKDIR}/README.txt ${D}${docdir}/helloworld
}</screen></para>

      <para>Note the:</para>

      <itemizedlist>
        <listitem>
          <para>use the <emphasis role="bold">install</emphasis> command to
          create directories and install the files, not cp.</para>
        </listitem>

        <listitem>
          <para>way directories are created before we attempt to install any
          files into them. The install command takes care of any
          subdirectories that are missing, so we only need to create the full
          path to the directory - no need to create the subdirectories.</para>
        </listitem>

        <listitem>
          <para>way we install everything into the destination directory via
          the use of the <emphasis role="bold">${D}
          </emphasis>variable.</para>
        </listitem>

        <listitem>
          <para>way we use variables to refer to the target directories, such
          as <emphasis role="bold">${bindir}</emphasis> and <emphasis
          role="bold">${docdir}</emphasis>.</para>
        </listitem>

        <listitem>
          <para>use of <emphasis role="bold">${WORKDIR}</emphasis> to get
          access to the <emphasis role="bold">README.txt</emphasis> file,
          which was provided via file:// URI.</para>
        </listitem>
      </itemizedlist>

      <para>We'll consider this release 0 and version 0.1 of a program called
      helloworld. So we'll name the recipe helloworld_0.1.bb:<screen>cat &gt; packages/helloworld/helloworld_0.1.bb
DESCRIPTION = "Hello world program"
PR = "r0"

SRC_URI = "file://helloworld.c \
           file://README.txt"

do_compile() {
        ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/helloworld.c -o helloworld
}

do_install() {
        install -m 0755 -d ${D}${bindir} ${D}${docdir}/helloworld
        install -m 0644 ${S}/helloworld ${D}${bindir}
        install -m 0644 ${WORKDIR}/README.txt ${D}${docdir}/helloworld
}
^D</screen>Now we are ready to build our package, hopefully it'll all work
      since it's such a simple example:<screen>~/oe%&gt; bitbake -b packages/helloworld/helloworld_0.1.bb
NOTE: package helloworld-0.1: started
NOTE: package helloworld-0.1-r0: task do_fetch: started
NOTE: package helloworld-0.1-r0: task do_fetch: completed
NOTE: package helloworld-0.1-r0: task do_unpack: started
NOTE: Unpacking /home/lenehan/devel/oe/local-packages/helloworld/files/helloworld.c to /home/lenehan/devel/oe/build/titan-glibc-25/tmp/work/helloworld-0.1-r0/
NOTE: Unpacking /home/lenehan/devel/oe/local-packages/helloworld/files/README.txt to /home/lenehan/devel/oe/build/titan-glibc-25/tmp/work/helloworld-0.1-r0/
NOTE: package helloworld-0.1-r0: task do_unpack: completed
NOTE: package helloworld-0.1-r0: task do_patch: started
NOTE: package helloworld-0.1-r0: task do_patch: completed
NOTE: package helloworld-0.1-r0: task do_configure: started
NOTE: package helloworld-0.1-r0: task do_configure: completed
NOTE: package helloworld-0.1-r0: task do_compile: started
NOTE: package helloworld-0.1-r0: task do_compile: completed
NOTE: package helloworld-0.1-r0: task do_install: started
NOTE: package helloworld-0.1-r0: task do_install: completed
NOTE: package helloworld-0.1-r0: task do_package: started
NOTE: package helloworld-0.1-r0: task do_package: completed
NOTE: package helloworld-0.1-r0: task do_package_write: started
NOTE: Not creating empty archive for helloworld-dbg-0.1-r0
Packaged contents of helloworld into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/helloworld_0.1-r0_sh4.ipk
Packaged contents of helloworld-doc into /home/lenehan/devel/oe/build/titan-glibc-25/tmp/deploy/ipk/helloworld-doc_0.1-r0_sh4.ipk
NOTE: Not creating empty archive for helloworld-dev-0.1-r0
NOTE: Not creating empty archive for helloworld-locale-0.1-r0
NOTE: package helloworld-0.1-r0: task do_package_write: completed
NOTE: package helloworld-0.1-r0: task do_populate_staging: started
NOTE: package helloworld-0.1-r0: task do_populate_staging: completed
NOTE: package helloworld-0.1-r0: task do_build: started
NOTE: package helloworld-0.1-r0: task do_build: completed
NOTE: package helloworld-0.1: completed
Build statistics:
  Attempted builds: 1
~/oe%&gt;</screen></para>

      <para>The package was successfully built, the output consists of two
      .ipkg files, which are ready to be installed on the target. One contains
      the binary and the other contains the readme file:<screen>~/oe%&gt; ls -l tmp/deploy/ipk/helloworld*
-rw-r--r--  1 lenehan lenehan 3040 Jan 12 14:46 tmp/deploy/ipk/helloworld_0.1-r0_sh4.ipk
-rw-r--r--  1 lenehan lenehan  768 Jan 12 14:46 tmp/deploy/ipk/helloworld-doc_0.1-r0_sh4.ipk
~/oe%&gt;</screen></para>

      <para>It's worthwhile looking at the working directory to see where
      various files ended up:<screen>~/oe%&gt; find tmp/work/helloworld-0.1-r0
tmp/work/helloworld-0.1-r0
tmp/work/helloworld-0.1-r0/helloworld-0.1
tmp/work/helloworld-0.1-r0/helloworld-0.1/patches
tmp/work/helloworld-0.1-r0/helloworld-0.1/helloworld
tmp/work/helloworld-0.1-r0/temp
tmp/work/helloworld-0.1-r0/temp/run.do_configure.21840
tmp/work/helloworld-0.1-r0/temp/log.do_stage.21840
tmp/work/helloworld-0.1-r0/temp/log.do_install.21840
tmp/work/helloworld-0.1-r0/temp/log.do_compile.21840
tmp/work/helloworld-0.1-r0/temp/run.do_stage.21840
tmp/work/helloworld-0.1-r0/temp/log.do_configure.21840
tmp/work/helloworld-0.1-r0/temp/run.do_install.21840
tmp/work/helloworld-0.1-r0/temp/run.do_compile.21840
tmp/work/helloworld-0.1-r0/install
tmp/work/helloworld-0.1-r0/install/helloworld-locale
tmp/work/helloworld-0.1-r0/install/helloworld-dbg
tmp/work/helloworld-0.1-r0/install/helloworld-dev
tmp/work/helloworld-0.1-r0/install/helloworld-doc
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc/helloworld
tmp/work/helloworld-0.1-r0/install/helloworld-doc/usr/share/doc/helloworld/README.txt
tmp/work/helloworld-0.1-r0/install/helloworld
tmp/work/helloworld-0.1-r0/install/helloworld/usr
tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin
tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin/helloworld
tmp/work/helloworld-0.1-r0/image
tmp/work/helloworld-0.1-r0/image/usr
tmp/work/helloworld-0.1-r0/image/usr/bin
tmp/work/helloworld-0.1-r0/image/usr/share
tmp/work/helloworld-0.1-r0/image/usr/share/doc
tmp/work/helloworld-0.1-r0/image/usr/share/doc/helloworld
tmp/work/helloworld-0.1-r0/helloworld.c
tmp/work/helloworld-0.1-r0/README.txt
~/oe%&gt;</screen>Things to note here are:</para>

      <itemizedlist>
        <listitem>
          <para>The two source files are in <emphasis
          role="bold">tmp/work/helloworld-0.1-r0</emphasis>, which is the
          working directory as specified via the <emphasis
          role="bold">${WORKDIR}</emphasis> variable;</para>
        </listitem>

        <listitem>
          <para>There's logs of the various tasks in <emphasis
          role="bold">tmp/work/helloworld-0.1-r0/temp</emphasis> which you can
          look at for more details on what was done in each task;</para>
        </listitem>

        <listitem>
          <para>There's an image directory at <emphasis
          role="bold">tmp/work/helloworld-0.1-r0/image</emphasis> which
          contains just the directories that were to be packaged up. This is
          actually the destination directory, as specified via the <emphasis
          role="bold">${D}</emphasis> variable. The two files that we
          installed were originally in here, but during packaging they were
          moved into the install area into a subdirectory specific to the
          package that was being created (remember we have a main package and
          a -doc package being created.</para>
        </listitem>

        <listitem>
          <para>The program was actually compiled in the <emphasis
          role="bold">tmp/work/helloworld-0.1-r0/helloworld-0.1</emphasis>
          directory, this is the source directory as specified via the
          <emphasis role="bold">${S}</emphasis> variable.</para>
        </listitem>

        <listitem>
          <para>There's an install directory at <emphasis
          role="bold">tmp/work/helloworld-0.1-r0/install</emphasis> which
          contains the packages that were being generated and the files that
          go in the package. So we can see that the helloworld-doc package
          contains the single file <emphasis
          role="bold">/usr/share/doc/helloworld/README.txt</emphasis>, the
          helloworld package contains the single file <emphasis
          role="bold">/usr/bin/helloworld</emphasis> and the -dev, -dbg and
          -local packages are all empty.</para>
        </listitem>
      </itemizedlist>

      <para>At this stage it's good to verify that we really did produce a
      binary for the target and not for our host system. We can check that
      with the file command:<screen>~/oe%&gt; file tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin/helloworld
tmp/work/helloworld-0.1-r0/install/helloworld/usr/bin/helloworld: ELF 32-bit LSB executable, Hitachi SH, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, not stripped
~/oe%&gt; file /bin/ls
/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), for GNU/Linux 2.4.0, stripped
~/oe%&gt;</screen>This shows us that the helloworld program is for an SH
      processor (obviously this will change depending on what your target
      system is), while checking the /bin/ls program on host shows us that the
      host system is an AMD X86-64 system. That's exactly what we
      wanted.</para>

      <para></para>
    </section>

    <section id="bb_autoconf_example" xreflabel="autoconf example">
      <title>An autotools package</title>

      <para>Now for an example of a package that uses autotools. These are
      programs that you need to run a configure script for, passing various
      parameters, and then make. To make these work when cross-compiling you
      need to provides a lot of variables to the configure script. But all the
      hard work as already been done for you. There's an <xref
      linkend="autotools_class" /> which takes care of most of the complexity
      of building an autotools based packages.</para>

      <para>Let's take a look at the tuxnes recipe which is an example of a
      very simple autotools based recipe:<screen>%~oe&gt; cat packages/tuxnes/tuxnes_0.75.bb
DESCRIPTION = "Tuxnes Nintendo (8bit) Emulator"
HOMEPAGE = "http://prdownloads.sourceforge.net/tuxnes/tuxnes-0.75.tar.gz"
LICENSE = "GPLv2"
SECTION = "x/games"
PRIORITY = "optional"
PR = "r1"

SRC_URI = "http://heanet.dl.sourceforge.net/sourceforge/tuxnes/tuxnes-0.75.tar.gz"

inherit autotools</screen></para>

      <para>This is a really simple recipe. There's the standard header that
      describes the package. Then the SRC_URI, which in this case is a http
      URL that causes the source code to be downloaded from the specified URI.
      And finally there's an "<emphasis role="bold">inherit
      autotools</emphasis>" command which loads the autotools class. The
      autotools class will take care of generating the require configure,
      compile and install tasks. So in this case there's nothing else to do -
      that's all there is to it.</para>

      <para>It would be nice if it was always this simple. Unfortunately
      there's usually a lot more involved for various reasons including the
      need to:</para>

      <itemizedlist>
        <listitem>
          <para>Pass parameters to configure to enable and disable
          features;</para>
        </listitem>

        <listitem>
          <para>Pass parameters to configure to specify where to find
          libraries and headers;</para>
        </listitem>

        <listitem>
          <para>Make modifications to prevent searching for headers and
          libraries in the normal locations (since they below to the host
          system, not the target);</para>
        </listitem>

        <listitem>
          <para>Make modifications to prevent the configure script from tying
          to compile and run programs - any programs it compiles will be for
          the target and not the host and so cannot be run.</para>
        </listitem>

        <listitem>
          <para>Manually implement staging scripts;</para>
        </listitem>

        <listitem>
          <para>Deal with lots of other more complex issues;</para>
        </listitem>
      </itemizedlist>

      <para>Some of these items are covered in more detail in the advanced
      autoconf section.</para>
    </section>
  </section>

  <section id="bb_depenencies" xreflabel="dependencies">
    <title>Dependencies: What's needed to build and/or run the
    package?</title>

    <para>Dependencies should be familiar to anyone who has used an .rpm and
    .deb based desktop distribution. A dependency is something that a package
    requires either to run the package (a run-time dependency) or to build the
    package (a build-time or compile-time, dependency).</para>

    <para>There are two variables provided to allow the specifications of
    dependencies:</para>

    <variablelist>
      <varlistentry>
        <term>DEPENDS</term>

        <listitem>
          <para>Specifies build-time dependencies, via a list of bitbake
          recipes to build prior to build the recipe. These are programs
          (flex-native) or libraries (libpcre) that are required in order to
          build the package.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RDEPENDS</term>

        <listitem>
          <para>Specifies run-time dependencies, via a list of packages to
          install prior to installing the current package. These are programs
          or libraries that are required in order to run the program. Note
          that libraries which are dynamically linked to an application will
          be automatically detected and added to <emphasis
          role="bold">RDEPENDS</emphasis> and therefore do not need to be
          explicitly declared. If a library was dynamically loaded then it
          would need to be explicitly listed.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>If we take openssh for an example, it requires zlib and openssl in
    order to both built and run. In the recipe we have:<screen>DEPENDS = "zlib openssl"</screen>This
    tells bitbake that it will need to build and stage zlib and openssl prior
    to trying to build openssh, since openssh requires both of them. Note that
    there is no <emphasis role="bold">RDEPENDS</emphasis> even though openssh
    requires both of them to run. The run time dependencies on libz1 (the name
    of the package containing the zlib library) and libssl0 (the name of the
    package containing the ssl library) are automatically determined and added
    via the auto shared libs dependency code.</para>
  </section>

  <section id="bb_messages" xreflabel="messages">
    <title>Messages: Letting the user know things</title>

    <para>[UNEDITED]</para>

    <para></para>

    <variablelist>
      <varlistentry>
        <term>oenote</term>

        <listitem>
          <para>Display some informational messages to the user.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oewarn</term>

        <listitem>
          <para>Display a warning to the user.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oedebug</term>

        <listitem>
          <para>Display an error message to the user and abort the
          action.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>oefatal</term>

        <listitem>
          <para>Display a debugging message to the user but only if they have
          requested debugging output.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>Of the four functions only oefatal will abort the currently
    executing task.</para>
  </section>

  <section id="bb_methods" xreflabel="methods">
    <title>Methods: Inbuilt methods to make your life easier</title>

    <para>oe_runmake</para>

    <para>oe_runconf</para>

    <para>oe_libinstall</para>
  </section>

  <section id="bb_packages" xreflabel="packages">
    <title>Packaging: Defining packages and their contents</title>

    <para>[</para>

    <para>Talk about multiple packages and putting things in those
    packages</para>

    <para>philosophy of packaging - dbg, doc, dev, main package, libs,
    additional</para>

    <para>PACKAGES</para>

    <para>FILES</para>

    <para>wildcards and how they effect dir/file selection</para>

    <para>debian naming?</para>

    <para>-dbg packages and how to handle them</para>

    <para>package ordering and how it effects wildcards</para>

    <para>modifying vs replacing PACKAGES</para>

    <para>"find tmp/&lt;package-name&gt;/install"</para>

    <para>]</para>

    <para></para>

    <para>The default assignment of PACKAGES and FILES is:</para>

    <variablelist>
      <varlistentry>
        <term>PACKAGES</term>

        <listitem>
          <para>Lists the names of each of the packages which are to be
          generated.<screen>PACKAGES = "${PN}-dbg ${PN} ${PN}-doc ${PN}-dev ${PN}-locale"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>FILES_${PN}</term>

        <listitem>
          <para>The base package, this includes everything needed to actually
          run the application on the target system.<screen>FILES_${PN} = "${bindir}/* ${sbindir}/* ${libexecdir}/* ${libdir}/lib*.so.* \
${sysconfdir} ${sharedstatedir} ${localstatedir} /bin/* /sbin/* \
/lib/*.so* ${datadir}/${PN} ${libdir}/${PN}/* ${datadir}/pixmaps \
${datadir}/applications ${datadir}/idl ${datadir}/omf \
${datadir}/sounds ${libdir}/bonobo/servers"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>FILES_${PN}-dbg</term>

        <listitem>
          <para>Non-stripped versions executable's. OE automatically runs
          strip on binary commands but leaves the originals in a .debug
          directory.<screen>FILES_${PN}-dbg = "${bindir}/.debug ${sbindir}/.debug \
${libexecdir}/.debug ${libdir}/.debug /bin/.debug /sbin/.debug \
/lib/.debug ${libdir}/${PN}/.debug"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>FILES_${PN}-doc</term>

        <listitem>
          <para>Documentation related files. All documentation is separated
          into it's own package so that it does not need to be installed
          unless explicitly required.<screen>FILES_${PN}-doc = "${docdir} ${mandir} ${infodir} ${datadir}/gtk-doc \
${datadir}/gnome/help"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>FILES_${PN}-dev</term>

        <listitem>
          <para>Development related files. Any headers, libraries and support
          files needed for development work on the target.<screen>FILES_${PN}-dev = "${includedir} ${libdir}/lib*.so ${libdir}/*.la
${libdir}/*.a ${libdir}/*.o ${libdir}/pkgconfig /lib/*.a /lib/*.o
${datadir}/aclocal"</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>FILES_${PN}-locale</term>

        <listitem>
          <para>Locale related files.<screen>FILES_${PN}-locale = "${datadir}/locale"</screen></para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para></para>
  </section>

  <section id="bb_tasks" xreflabel="tasks">
    <title>Tasks: Playing with tasks</title>

    <para>Bitbake steps through a series of tasks when building a recipe.
    Sometimes you need to explicitly define what a class does, such as
    providing a <emphasis role="bold">do_install</emphasis> function to
    implement the <emphasis>install</emphasis> task in a recipe and sometimes
    they are provided for you by common classes, such as the autotools class
    providing the default implementations of <emphasis>configure</emphasis>,
    <emphasis>compile</emphasis> and <emphasis>install</emphasis>
    tasks.</para>

    <para>There are several methods available to modify the tasks that are
    being run:</para>

    <variablelist>
      <varlistentry>
        <term>Overriding the default task implementation</term>

        <listitem>
          <para>By defining your own implementation of task you'll override
          any default or class provided implementations.</para>

          <para>For example, you can define you own implementation of the
          compile task to override any default implementation:<screen>do_compile() {
      oe_runmake DESTDIR=${D}
}</screen></para>

          <para>If you with to totally prevent the task from running you need
          to define your own empty implementation. This is typically done via
          the definition of the task using a single colon:<screen>do_configure() {
    :
}</screen></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Appending or prepending to the task</term>

        <listitem>
          <para>Sometime you want the default implementation, but you require
          addition functionality. This can done by appending or pre-pending
          additional functionality onto the task.</para>

          <para>The following example from units shows an example of
          installing an addition file which for some reason was not installed
          via the autotools normal <emphasis>install</emphasis> task:<screen>do_install_append() {
       install -d ${D}${datadir}
       install -m 0655 units.dat ${D}${datadir}
}

</screen></para>

          <para>The following example from the cherokee recipe show an example
          of adding functionality prior to the default
          <emphasis>install</emphasis> task. In this case it compiles a
          program that is used during installation natively so that it will
          work on the host. Without this the autotools default
          <emphasis>install</emphasis> task would fail since it'd try to run
          the program on the host which was compiled for the target:<screen>do_install_prepend () {
        # It only needs this app during the install, so compile it natively
        $BUILD_CC -DHAVE_SYS_STAT_H -o cherokee_replace cherokee_replace.c
}
</screen></para>

          <para></para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Defining a new task</term>

        <listitem>
          <para>Another option is define a totally new task, and then register
          that with bitbake so that it runs in between two of the existing
          tasks.</para>

          <para>The following example shows a situation in which a cvs tree
          needs to be copied over the top of an extracted tar.gz archive, and
          this needs to be done before any local patches are applied. So a new
          task is defined to perform this action, and then that task is
          registered to run between the existing <emphasis>unpack</emphasis>
          and <emphasis>patch</emphasis> tasks:<screen>do_unpack_extra(){
    cp -pPR ${WORKDIR}/linux/* ${S}
}
addtask unpack_extra after do_unpack before do_patch</screen></para>

          <note>
            <para>The task to add does not have the do_ prepended to it,
            however the tasks to insert it after and before do have the _do
            prepended. No errors will be generated if this is wrong, the
            additional task simple won't be executed.</para>
          </note>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>Using overrides</term>

        <listitem>
          <para>Overrides (described fully elsewhere) allow for various
          functionality to be performed conditionally based on the target
          machine, distribution, architecture etc.</para>

          <para>While not commonly used it is possible to use overrides when
          defining tasks. The following example from udev shows an additional
          file being installed for the specified machine only by performing an
          append to the <emphasis>install</emphasis> task for the h2200
          machine only:<screen>do_install_append_h2200() {
    install -m 0644 ${WORKDIR}/50-hostap_cs.rules         ${D}${sysconfdir}/udev/rules.d/50-hostap_cs.rules
}</screen></para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section>

  <section id="bb_classes" xreflabel="classes">
    <title>Classes: The separation of common functionality</title>

    <para>[</para>

    <para>what are classes</para>

    <para>some examples - autotools, update-rc.d, distutils, cpan</para>

    <para>]</para>
  </section>

  <section id="bb_staging" xreflabel="staging">
    <title>Staging: Making includes and libraries available for
    building</title>

    <para>[</para>

    <para>Why staging</para>

    <para>where staging to</para>

    <para>what does/does not go in staging</para>

    <para>]</para>
  </section>

  <section id="bb_autoconf" xreflabel="about autoconf">
    <title>Autoconf: All about autotools</title>

    <para>[</para>

    <para>More about building autoconf packages</para>

    <para>EXTRA_OECONF</para>

    <para>Problems with /usr/include</para>

    <para>Configuring to search on staging</para>

    <para>-L${STAGING_LIBDIR} vs ${TARGET_LDFLAGS}</para>

    <para>site files</para>

    <para>refer to ref manual for site files info</para>

    <para>]</para>
  </section>

  <section id="bb_installation_scripts" xreflabel="installation scripts">
    <title>Installation scripts: Running scripts during package install and/or
    removal</title>

    <para>[</para>

    <para>Talk about pre and post inst/remove scripts</para>

    <para>Talk about "sh" syntax (ie, vs "bash" syntax)</para>

    <para>Talk about offline install stuff</para>

    <para>Make note about how classes can effect this</para>

    <para>]</para>
  </section>

  <section id="bb_conffiles" xreflabel="conf files">
    <title>Configuration files</title>

    <para>Configuration files that are installed as part of a package require
    special handling. Without special handling as soon as the user upgrades to
    a new version of the package then changes they have made to the
    configuration files will be lost.</para>

    <para>In order to prevent this from happening you need to tell the
    packaging system which files are configuration files. Such files will
    result in the user being asked how the user wants to handle any
    configuration file changes (if any), as shown in this example:<screen>Downloading http://nynaeve.twibble.org/ipkg-titan-glibc//./p3scan_2.9.05d-r1_sh4.ipk
    Configuration file '/etc/p3scan/p3scan.conf'
    ==&gt; File on system created by you or by a script.
    ==&gt; File also in package provided by package maintainer.
       What would you like to do about it ?  Your options are:
        Y or I  : install the package maintainer's version
        N or O  : keep your currently-installed version
          D     : show the differences between the versions (if diff is installed)
     The default action is to keep your current version.
    *** p3scan.conf (Y/I/N/O/D) [default=N] ?</screen>To declare a file as a
    configuration file you need to define the
    <command>CONFFILES_&lt;pkgname&gt;</command> variable as a whitespace
    separated list of configuration files. The following example from clamav
    shows two files being marked as configuration files:<screen>CONFFILES_${PN}-daemon = "${sysconfdir}/clamd.conf \
                          ${sysconfdir}/default/clamav-daemon"</screen>Note
    the user of <command>${PN}-daemon</command> as the package name. The
    <command>${PN}</command> variable will expand to <command>clamav</command>
    and therefore these conf files are declared as being in the clamav-daemon
    package.</para>
  </section>

  <section id="bb_package_relationships"
           xreflabel="package relationships files">
    <title>Package relationships</title>

    <para>Explicit relationships between packages are support by packaging
    formats such as ipkg and deb. These relationships include describing
    conflicting packages and recommended packages.</para>

    <para>The following variables control the package relationships in the
    recipes:</para>

    <variablelist>
      <varlistentry>
        <term>RRECOMMENDS</term>

        <listitem>
          <para>Used to specify other packages that are recommended to be
          installed when this package is installed. Generally this means while
          the recommended packages are not required they provide some sort of
          functionality which users would usually want.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RCONFLICTS</term>

        <listitem>
          <para>Used to specify other packages that conflict with this
          package. Two packages that conflict cannot be installed at the same
          time.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>RPROVIDES</term>

        <listitem>
          <para>Used to explicitly specify what a package provides at runtime.
          For example hotplug support is provided by several packages, such as
          udev and linux-hotplug. Both declare that they runtime provide
          "hotplug". So any packages that require "hotplug" to work simply
          declare that it RDEPENDS on "hotplug". It's up to the distribution
          to specify which actual implementation of "virtual/xserver" is
          used.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term>PROVIDES</term>

        <listitem>
          <para>Used to explicitly specify what a package provides at build
          time. This is typically used when two or more packages can provide
          the same functionality. For example there are several different X
          servers in OpenEmbedded, and each as declared as providing
          "virtual/xserver". Therefore a package that depends on an X server
          to build can simply declare that it DEPENDS on "virtual/xserver".
          It's up to the distribution to specify which actual implementation
          of "virtual/xserver" is used.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para></para>
  </section>

  <section id="bb_fakeroot" xreflabel="fakeroot">
    <title>Fakeroot: Dealing with the need for "root"</title>

    <para>Sometimes packages requires root permissions in order to perform
    some action, such as changing user or group owners or creating device
    nodes. Since OpenEmbedded will not keep the user and group information
    it's usually preferably to remove that from the makefiles. For device
    nodes it's usually preferably to create them from the initial device node
    lists or via udev configuration.</para>

    <para>However if you can't get by without root permissions then you can
    use <xref linkend="fakeroot" /> to simulate a root environment, without
    the need to really give root access.</para>

    <para>Using <xref linkend="fakeroot" /> is done by prefixing the
    task:<screen>fakeroot do_install() {</screen>Since this requires fakeroot
    you also need to add a dependency on
    <command>fakeroot-native</command>:<screen>DEPENDS = "fakeroot-native"</screen>See
    the fuse recipe for an example. Further information on <xref
    linkend="fakeroot" />, including a description of it works, is provided in
    the reference section: <xref linkend="fakeroot" />.</para>
  </section>

  <section id="bb_native" xreflabel="native">
    <title>Native: Packages for the build host</title>

    <para>Talk about native packages</para>
  </section>

  <section id="bb_development" xreflabel="development">
    <title>Development: Strategies for developing recipes</title>

    <para>Talk about how to go about developing things</para>
  </section>

  <section id="bb_advanced_versioning" xreflabel="advanced versioning">
    <title>Advanced versioning: How to deal with rc and pre versions</title>

    <para>Special care needs to be taken when specify the version number for
    rc and pre versions of packages.</para>

    <para>Consider the case where we have an existing 1.5 version and there's
    a new 1.6-rc1 release that you want to add.</para>

    <itemizedlist>
      <listitem>
        <para>1.5: Existing version;</para>
      </listitem>

      <listitem>
        <para>1.6-rc1: New version.</para>
      </listitem>
    </itemizedlist>

    <para>If the new package is given the version number 1.6-rc1 then
    everything will work fine initially. However when the final release
    happens it will be called 1.6. If you now create a 1.6 version of the
    package you'll find that the packages are sorted into the following
    order:</para>

    <orderedlist>
      <listitem>
        <para>1.5</para>
      </listitem>

      <listitem>
        <para>1.6</para>
      </listitem>

      <listitem>
        <para>1.6-rc1</para>
      </listitem>
    </orderedlist>

    <para>This in turn result in packaging system, such as ipkg, considering
    the released version to be older then the rc version.</para>

    <para>In OpenEmbedded the correct naming of pre and rc versions is to use
    the previous version number followed by a + followed by the new version
    number. So the 1.6-rc1 release would be given the version number:</para>

    <itemizedlist>
      <listitem>
        <para>1.5+1.6-rc1</para>
      </listitem>
    </itemizedlist>

    <para>These would result in the eventually ordering being:</para>

    <orderedlist>
      <listitem>
        <para>1.5</para>
      </listitem>

      <listitem>
        <para>1.5+1.6-rc1</para>
      </listitem>

      <listitem>
        <para>1.6</para>
      </listitem>
    </orderedlist>

    <para>This is the correct order and the packaging system will now work as
    expected.</para>
  </section>

  <section id="bb_includes" xreflabel="includes">
    <title>Includes: Reusing recipe contents for multiple versions (and other
    purposes)</title>

    <para>Talk about the use of include and require and .inc files and how to
    separate these out.</para>
  </section>

  <section id="bb_advanced_python" xreflabel="advanced python">
    <title>Python: Advanced functionality with python</title>

    <para>Talk about using python code in recipes</para>

    <para>Samples of useful python code.</para>
  </section>

  <section id="bb_defaultpreference" xreflabel="default preference">
    <title>Preferences: How to disable packages</title>

    <para>Talk about using DEFAULT_PREFERENCE</para>

    <para>Why you should use it.</para>

    <para>Using overrides &amp; preferences together.</para>
  </section>

  <section id="bb_initscripts" xreflabel="dinitscripts">
    <title>Initscripts: How to handle daemons</title>

    <para>update-rc.d class</para>

    <para>sh vs bash</para>

    <para>start/stop/restart params</para>

    <para>sample / standard script format</para>

    <para>note about volatiles being described below</para>

    <para>reference section for more info</para>
  </section>

  <section id="bb_alternatives" xreflabel="alternatives">
    <title>Alternatives: How to handle the same command in multiple
    packages</title>

    <para>Why you should care</para>

    <para>Using them</para>

    <para>reference section for more info</para>
  </section>

  <section id="bb_volatiles" xreflabel="volatiles">
    <title>Volatiles: How to handle the /var directory</title>

    <para>[</para>

    <para>Talk about tmpfs for var</para>

    <para>Talk about how volatiles work</para>

    <para>Talk about logging via syslog so non-disk logs will may be
    used</para>

    <para>Talk about default volatiles</para>

    <para>reference section for more info</para>

    <para>]</para>

    <para>The /var directory is for storing volatile information, that is
    information which is constantly changing and which in general may be
    easily recreated. In embedded applications it is often desirable that such
    files are not stored on disk or flash for various reasons include possible
    reduced lifetime of the flash, limited storage space or to ensure
    filesystem corruption cannot occur due to a sudden power loss.</para>

    <para>For these reasons many of the OpenEmbedded distributions use a tmpfs
    memory based filesystem for /var instead of a disk or flash based
    filesystem. The consequence of this is that all contents of the /var
    directory is lost when the device is powered off or restarted. Therefore
    special handling of /var is required in all packages to ensure that they
    don't restrict the options available to individual distributions. This
    special handling is provided via the populate-volatiles.sh script.</para>

    <para>If your package requires directory, symlinks or files in /var then
    you should be using the populate-volatiles facilities.</para>

    <para></para>

    <section>
      <title>Declaring volatiles</title>

      <para></para>

      <para>- don't include /var stuff in packages</para>

      <para>- any expect dirs in def volatiles to exist</para>

      <para>- add volatiles file for any other distributions</para>
    </section>

    <section>
      <title>Logging and log files</title>

      <para>As a consequence of the non-volatile and/or small capacity of the
      /var file system some distributions choose methods of logging other than
      writing to a file. The most typical is the use of an in-memory circular
      log buffer which can be read using the logread command.</para>

      <para>To ensure that each distribution is able to implement logging in a
      method that is suitable for its goals all packages should be configured
      by default to log via syslog, and not log directly to a file, if
      possible. If the distribution and/or end-user requires logging to a file
      then they can configured syslog and/or your application to implement
      this.</para>
    </section>

    <section>
      <title>Summary</title>

      <para>In summary the following are required when dealing with
      <command>/var</command>:</para>

      <itemizedlist>
        <listitem>
          <para>Configure all logging to use syslog whenever possible. This
          leaves the decision on where to log upto the individual
          distributions.</para>
        </listitem>

        <listitem>
          <para>Don't include any <command>/var</command> directories, file or
          symlinks in packages. They would be lost on a reboot and so should
          not be included in packages.</para>
        </listitem>

        <listitem>
          <para>The only directories that you can assume exist are those
          listed in the default volatiles file:
          <command>packages/initscripts/initscripts-1.0/volatiles</command>.</para>
        </listitem>

        <listitem>
          <para>For any other directories, files or links that are required in
          <command>/var</command> you should install your own volatiles list
          as part of the package.</para>
        </listitem>
      </itemizedlist>
    </section>
  </section>

  <section>
    <title>STUFF STILL TO BE CONSIDERED/ADDED</title>

    <para>about optimisation</para>

    <para>about download directories</para>

    <para>about parallel builds</para>

    <para>about determening endianess (aka net-snmp, openssl, hping etc
    style)</para>

    <para>about adding users/groups</para>

    <para>about PACKAGES_DYNAMIC</para>

    <para>about LEAD_SONAME</para>

    <para>about "python () {" - looks like it is always run when a recipe is
    parsed? see pam/libpam</para>

    <para>about SRCDATE with svn/cvs?</para>

    <para>about INHIBIT_DEFAULT_DEPS?</para>

    <para>about COMPATIBLE_MACHINE and COMPATIBLE_HOST</para>

    <para></para>
  </section>
</chapter>