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
|
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="chapter_common_use_cases">
<title>Common Use-cases/tasks</title>
<section id="commonuse_new_distro">
<title>Creating a new Distribution</title>
<para>Creating a new distribution is not complicated, however we urge you
to try existing distributions first, because it's also very easy to do
wrong. The config need to be created in /conf/distro directory. So what
has to be inside? <itemizedlist>
<listitem>
<para><command>DISTRO_VERSION</command> so users will know which
version of distribution they use.</para>
</listitem>
<listitem>
<para><command>DISTRO_TYPE</command> (release/debug) variable is
used in some recipes to enable/disable some features - for example
kernel output on screen for "debug" builds.</para>
</listitem>
<listitem>
<para>Type of libc used: will it be glibc
(<command>TARGET_OS</command> = "linux") or uclibc
(<command>TARGET_OS</command> = "linux-uclibc")?</para>
</listitem>
<listitem>
<para>Toolchain versions - for example gcc 3.4.4 based distro will
have: <screen>
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc:gcc-cross"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross"
PREFERRED_VERSION_binutils = "2.16"
PREFERRED_VERSION_binutils-cross = "2.16"
PREFERRED_VERSION_gcc = "3.4.4"
PREFERRED_VERSION_gcc-cross = "3.4.4"
PREFERRED_VERSION_gcc-initial-cross = "3.4.4"
</screen></para>
</listitem>
<listitem>
<para><command>DISTRO_FEATURES</command> which describe which
features distro has. More about it in <link
linkend="task-base">task-base</link> section.</para>
</listitem>
<listitem>
<para>Versions of kernels used for supported devices: <screen>
PREFERRED_VERSION_linux-omap1_omap5912osk ?= "2.6.18+git"
PREFERRED_VERSION_linux-openzaurus ?= "2.6.17"
</screen></para>
</listitem>
<listitem>
<para>To get more stable build it is good to make use of
sane-srcdates.inc file which contain working SRCDATE for many of
floating recipes. <screen>
require conf/distro/include/sane-srcdates.inc
</screen> It also should have global <command>SRCDATE</command>
value set (format is ISO date: YYYYMMDD): <screen>
SRCDATE = "20061014"
</screen></para>
</listitem>
</itemizedlist></para>
</section>
<section id="commonuse_new_machine">
<title>Adding a new Machine</title>
<para>To be able to build for device OpenEmbedded have to know it, so
machine config file need to be written. All those configs are stored in
/conf/machine/ directory.</para>
<para>As usual some variables are required: <itemizedlist>
<listitem>
<para><command>TARGET_ARCH</command> which describe which CPU
architecture does machine use.</para>
</listitem>
<listitem>
<para><command>MACHINE_FEATURES</command> which describe which
features device has. More about it in <link
linkend="task-base">task-base</link> section.</para>
</listitem>
<listitem>
<para><command>PREFERRED_PROVIDER_virtual/kernel</command> has to
point into proper kernel recipe for this machine.</para>
</listitem>
</itemizedlist></para>
<para>Next kernel recipe needs to be added.</para>
</section>
<section id="commonuse_new_package">
<title>Adding a new Package</title>
<para>This section is a stub, help us by expanding it. Learn by example, go through the
recipes that are already there and mimic them to do what you want.</para>
<section>
<title>building from unstable source code</title>
<para>Building against the latest, bleeding-edge source has some intricacies of its own.
For one, it is desirable to pin down a souce code revision that is known to build to
prevent random breakage in OE at the most inopportune time for all OE users. Here is
how to do that properly.
<itemizedlist>
<listitem><para>for svn: add 'PV = "1.1+svnr${SRCREV}"' to your bb file.</para></listitem>
<listitem><para>for cvs: add 'PV = "1.1+cvs${SRCREV}"' to your bb file.</para></listitem>
</itemizedlist>
Accompany either with an entry to conf/distro/include/sane-srcrevs.inc for a revision that you know
builds successfully.
</para>
<para>
If you really absolutely have to follow the latest commits, you can do that by adding
'SRCREV_pn-linux-davinci ?= ${AUTOREV}' to your local.conf, for example. In this case,
you'd build against the most recent and unstable source for the pn-linux-davinci package.
</para>
</section>
</section>
<section id="commonuse_new_image">
<title>Creating your own image</title>
<para>Creating own image is easy - only few variables needs to be set:
<itemizedlist>
<listitem>
<para><command>IMAGE_BASENAME</command> to give a name for your own
image</para>
</listitem>
<listitem>
<para><command>PACKAGE_INSTALL</command> to give a list of packages
to install into the image</para>
</listitem>
<listitem>
<para><command>RDEPENDS</command> to give a list of recipes which
are needed to be built to create this image</para>
</listitem>
<listitem>
<para><command>IMAGE_LINGUAS</command> is an optional list of
languages which has to be installed into the image</para>
</listitem>
</itemizedlist> Then adding of the <emphasis>image</emphasis> class use:
<screen>
inherit image
</screen> And the image recipe is ready for usage.</para>
</section>
<section id="commonuse_prebuilt_toolchain">
<title>Using a prebuilt toolchain to create your packages</title>
<para>It might be necessary to integrate a prebuilt toolchain and other
libraries but still be use OpenEmbedded to build packages. One of many
approaches is shown and discussed here.</para>
<section>
<title>The toolchain</title>
<para>We assume the toolchain provides a C and C++ compiler, an
assembler and other tools to build packages. The list below shows a gcc
3.4.4 toolchain for ARM architectures using glibc. We assume that the
toolchain is in your <command>PATH</command>.</para>
<screen>
<command>ls</command> pre-built/cross/bin
arm-linux-g++
arm-linux-ld
arm-linux-ranlib
arm-linux-ar
arm-linux-g77
arm-linux-readelf
arm-linux-as
arm-linux-gcc
arm-linux-gcc-3.4.4
arm-linux-c++
arm-linux-size
arm-linux-c++filt
arm-linux-nm
arm-linux-strings
arm-linux-cpp
arm-linux-objcopy
arm-linux-strip
arm-linux-objdump
</screen>
</section>
<section>
<title>The prebuilt libraries</title>
<para>We need the header files and the libraries itself. The following
directory layout is assume. <command>PRE_BUILT</command> has two
subdirectories one is called <emphasis>include</emphasis> and holds the
header files and the other directory is called <emphasis>lib</emphasis>
and holds the shared and static libraries. Additionally a Qt2 directory
is present having a <emphasis>include</emphasis> and
<emphasis>lib</emphasis> sub-directory.</para>
<screen>
<command>ls</command> $PRE_BUILT
include
lib
qt2
</screen>
</section>
<section>
<title>Setting up OpenEmbedded</title>
<para>OpenEmbedded will be setup here. We assume that your machine and
distribution is not part of OpenEmbedded and they will be created ad-hoc
in the <emphasis>local.conf</emphasis> file. You will need to have
<application>BitBake</application> and a current OpenEmbedded version
available.</para>
<section>
<title>Sourcable script</title>
<para>To ease the usage of OpenEmbedded we start by creating a
source-able script. This is actually a small variation from the
already seen script. We will name it <emphasis>build_source</emphasis>
and you will need to source it.</para>
<screen>
BITBAKE_PATH=/where/is/bitbake/bin
TOOLCHAIN=/where/is/toolchain/bin
HOST_TOOLS=/where/is/hosttools/bin
export PRE_BUILT=/where/is/pre-built
export PATH=$BITBAKE_PATH:$TOOLCHAIN:$HOST_TOOLS:$PATH
export OEDIR=$PWD
export LOCALDIR=$PWD/secret-isv
</screen>
<para>Use <command>source build_source</command> to source the script,
use <command>env</command> to check that the variable where
exported.</para>
</section>
<section>
<title>Creating the local.conf</title>
<para>We will configure OpenEmbedded now, it is very similar to what
we have done above.</para>
<screen>
DL_DIR = "${OEDIR}/sources"
BBFILES := "${OEDIR}/openembedded/packages/*/*.bb ${LOCALDIR}/packages/*/*.bb"
BBFILE_COLLECTIONS = "upstream local"
BBFILE_PATTERN_upstream = "^${OEDIR}/openembedded/packages/"
BBFILE_PATTERN_local = "^${LOCALDIR}/packages/"
BBFILE_PRIORITY_upstream = "5"
BBFILE_PRIORITY_local = "10"
BBMASK = ""
</screen>
<para>${OEDIR}/openembedded will be a upstream release of
OpenEmbedded. Above we have assumed it is in the current working
directory. Additionally we have a ${LOCALDIR}, we combine these two
directories as a special <link linkend="collections">BitBake
Collection</link>.</para>
<screen>
#
# machine stuff
#
MACHINE = "secret-killer"
PACKAGE_EXTRA_ARCHS = "armv4 armv4t armv5te iwmmxt xscale""
TARGET_CC_ARCH = "-mcpu=xscale -mtune=iwmmxt"
TARGET_ARCH = "arm"
PACKAGE_ARCH="xscale"
</screen>
<para>We tell OpenEmbedded that we build for the ARM platform and
optimize for xscale and iwmmxt.</para>
<screen>
INHERIT += " package_ipk debian"
TARGET_OS = "linux"
TARGET_FPU = "soft"
DISTRO = "secret-disro"
DISTRO_NAME = "secret-distro"
DISTRO_VERSION = "x.y.z"
DISTRO_TYPE = "release"
</screen>
<para>Create a distribution ad-hoc as well. We tell OpenEmbedded that
we build for linux and glibc using soft float as fpu. If your
toolchain is a uclibc toolchain you will need to set
<command>TARGET_OS</command> to linux-uclibc.</para>
<screen>
export CC="${CCACHE}arm-linux-gcc-3.4.4 ${HOST_CC_ARCH}"
export CXX="${CCACHE}arm-linux-g++ ${HOST_CC_ARCH}"
export CPP="arm-linux-gcc-3.4.4 -E"
export LD="arm-linux-ld"
export AR="arm-linux-ar"
export AS="arm-linux-as"
export RANLIB="arm-linux-ranlib"
export STRIP="arm-linux-strip"
</screen>
<para>The above variables replace the ones from
<emphasis>bitbake.conf</emphasis>. This will make OpenEmbedded use the
prebuilt toolchain.</para>
<screen>
#
# point OE to the lib and include directory
#
TARGET_CPPFLAGS_append = " -I${PRE_BUILT}/include "
TARGET_LDFLAGS_prepend = " -L${PRE_BUILT}/qt2/lib -L${PRE_BUILT}/lib \
-Wl,-rpath-link,${PRE_BUILT}/lib -Wl,-rpath-link,${PRE_BUILT}/qt2/lib "
# special to Qt/Qtopia
QTDIR = "${PRE_BUILT}/qt2"
QPEDIR = "${PRE_BUILT}"
palmtopdir = "/opt/Qtopia"
palmqtdir = "/opt/Qtopia"
</screen>
<para>We will add the <command>PRE_BUILT</command> libraries to the
include and library paths. And the same is done for the special
version of Qt we have in your <command>PRE_BUILT</command>
directory.</para>
<screen>
ASSUME_PROVIDED += " virtual/${TARGET_PREFIX}gcc "
ASSUME_PROVIDED += " virtual/libc "
ASSUME_PROVIDED += " virtual/qte "
ASSUME_PROVIDED += " virtual/libqpe "
ASSUME_PROVIDED += " libqpe-opie "
</screen>
<para>Now we have told <application>BitBake</application> that the C
library, compiler and Qtopia is already provided. These lines will
avoid building binutils, gcc initial, glibc, gcc.</para>
<screen>
<command>source</command> build_source
<command>bitbake</command> your-killer-app
</screen>
<para>You should be able to create the packages you want to using the
prebuilt toolchain now.</para>
</section>
</section>
<section>
<title>Useful hints</title>
<para>If you have more prebuilt libraries you need to add additional
<command>ASSUME_PROVIDED</command> lines to your
<emphasis>local.conf</emphasis>. Using <command>bitbake -vvv
PACKAGE</command> you can easily see the package names you could
<command>ASSUME_PROVIDED</command> if you have some prebuilt.</para>
</section>
<section>
<title>Issues with this approach</title>
<screen>
NOTE: Couldn't find shared library provider for libqtopia.so.1
NOTE: Couldn't find shared library provider for libqtopia2.so.2
NOTE: Couldn't find shared library provider for libqpe.so.1
NOTE: Couldn't find shared library provider for libpthread.so.0
NOTE: Couldn't find shared library provider for libstdc++.so.6
NOTE: Couldn't find shared library provider for libqte.so.2
NOTE: Couldn't find shared library provider for libgcc_s.so.1
NOTE: Couldn't find shared library provider for libc.so.6
NOTE: Couldn't find shared library provider for libm.so.6
</screen>
<para>OpenEmbedded tries to automatically add run-time dependencies
(RDEPENDS) to the package. It uses the <emphasis><link
linkend="shlibs">shlibs</link></emphasis> system to do add them, in this
case it was not able to find packages providing these libraries as they
are prebuilt. This means they will not be added to the RDEPENDS of the
just created package. The result can be fatal. If you use OpenEmbedded
to create images you will end up with a image without a libc being
installed. This will lead to a fatal failure. To workaround this issue
you could create a package for the metadata to install every needed
library and use ${BOOTSTRAP_EXTRA_RDEPENDS} to make sure this package is
installed when creating images.</para>
<para>However, the correct way to resolve this is to provide explicit
mapping using ASSUME_SHLIBS variable. For example, for the libraries
above (partial):
<screen>
ASSUME_SHLIBS = "libqtopia2.so.2:qtopia2_2.4 libc.so.6:libc"
</screen>
The format is shlib_file_name:package[_version]. If a version is specified it will be
used as the minimal (>=) version for the dependency.</para>
</section>
</section>
<section id="commonuse_new_package_format">
<title>Using a new package format</title>
<para>This section is a stub, help us by expanding it</para>
</section>
</chapter>
|