Adding Packages To Base Image
For the most part, OE (OpenEmbedded) is easy to use, once you get to know its quirks.
Adding packages to an image is essentially that of choosing what package(s) you want,
adding them to the list of recipes, then rebuilding the image. It is a bit more
involved, but it is not too complicated to do this. Once you understand the process,
it actually becomes easy to do.
As an example, what we are going to do now is to add a set of development tools
into the base-image.
TopPackage Selections
First of all, how do package lists (recipes) work? Very simply, OE is a hierarchy
of files / packages. For example, if you were to install openssh (a secure shell
similar to dropbear) into the image, you would find that openssh requires that zlib
and the openssl libraries as well. We can look at the recipe for openssh by opening
'meta/packages/openssh/openssh_4.6p1.bb' recipe and look at the 'DEPENDS'.
Not to go into a lot of detail about how a recipe is constructed, look at the openssh
recipe to get an idea of what it does. It names the source files and patch files needed
to build openssh. It also has instructions (modifications to basic OE build steps)
included to guide OE into building the package. There is quite a bit there to building
this package, but you don't need to know all that. You just assume that someone else
knew what they were doing to build the recipe and now you just add it to your list
of 'ingredients'.
Something else that you should notice is that version 4.6 is not the only openssh version
that is available. Versions prior to that are also available. But, OE choses the
highest numbered version to use. You can specify a certain version to use in your
image, but I won't go into how to use a specific version of a package. That is beyond
the scope of the documentation, at this point.
TopThe OE Hierarchy
An OE project can be thought of as being four areas, or realms: local definition,
package recipes, image template, and, the task list(s). While these four realms are
inter-related, they behave very much as seperate entities being loosely bound together.
Always think of an OE project as having those four sections.
The local definiton is the highest level of abstraction. The 'build/conf/local' describes
the distro to use and the machine to use. The 'stable' branch uses 'angstrom-2007.1', do
not change that, it is STABLE! The machine definition in 'meta/conf/machine/zipit2.conf'
describes the hardware platform. We also will use that conf file to add more packages.
There is another way to add packages to a distro/machine, but it is not yet been
'stabilized'.
When you invoke bitbake to build an image, you specify the image to use (e.g.
'meta/packages/images/base-image.bb'). Entries within the machine and distro file may
conditionally cause packages to be auto-magically selected. Case in point would be
saying something like 'DISTRO_FEATURES += "wifi "' in the distro conf file. Naming a
general class of functionality could be expanded via the tasklist into adding certain
wifi packages to your image.
We already went into what a recipe was, in the prior section, so the final section
(or realm) is the task lists.
A task lists is just that, it is a list of tasks to be performed to achieve the
desired image. This list is ordered by dependency as one package may need header
files from a library. Thus, the library must be built first.
You don't need to memorize these realms, just be aware of their existance and how
they relate to each other.
TopAdding Development Tools To The Image
Here we go, you have already built the base-image, and tested it, correct? That image
is what we will build upon. GOOD NEWS! You don't have to build everything over again!
You are going to be adding to it.
Edit the 'meta/conf/machine/zipit2.conf' file and these lines to the end of that file:
MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "gcc binutils make patch patchutils diffstat diffutils "
MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "cpp automake flex bison gawk sed grep perl gcc-symlinks "
MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "g++-symlinks binutils-symlinks libc6-dev flex-dev "
MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "autoconf libstdc++-dev "
IMPORTANT! Note that '+=' is used instead of just '=', always assume that your OE
variable already contains something and add to it. Also note that a trailing blank
must appear at the end of the quoted string. This is to allow for further '+=' appending.
Since we changed the list of ingredients, we have to rebuild our list of tasks. What
task to rebuild may take some research as you move on into building the GPE and OPIE
images. We look at the image to see what task(s) it uses ('meta/packages/images/base-image.bb')
and find that it uses task-boot. So, rebuild the task-boot list with:
[tom@slushy ZipitZ2]$ bitbake -c rebuild task-boot
Next, rebuild the image:
[tom@slushy ZipitZ2]$ bitbake base-image
When it finishes, your new image for the SD card will be about 130Meg (c++
takes up a lot of room!).
This image build will skip all the prior building that was done before and just build
what is necessary for the new packages (about another 300 steps). After the image
finishes, install it with the prepSDcard.pl script as you did before. Also, if you
want to login into it from the wifi, you will need to add that user again. Once the Zipit
boots, you should now be able to compile, and run, a simple hello-world.c program
on the Z2:
tom@zipit2:~$ cat hello.c
#include <stdio.h>
int main (void)
{
printf ("Hello World\n");
return 0;
}
tom@zipit2:~$ arm-angstrom-linux-gcc hello.c
tom@zipit2:~$ ls
a.out* hello.c
tom@zipit2:~$ ./a.out
Hello World
tom@zipit2:~$
Or, if you like, try a C++ program:
tom@zipit2:~$ cat hello.cpp
/* the first C++ program - just outputs `Hello, World!' */
#include <iostream> // declarations for I/O
int main() // main function main()
{
/* print `Hello, World!' on standard output channel std::cout
* followed by an endline (std::endl) */
std::cout << "Hello, World!" << std::endl;
}
tom@zipit2:~$ arm-angstrom-linux-g++ hello.cpp
tom@zipit2:~$ ./a.out
Hello, World!
tom@zipit2:~$
And, finally, from perl:
tom@zipit2:~$ cat hello.pl
#!/usr/bin/perl
print ("Hello there World\n");
tom@zipit2:~$ chmod u+x hello.pl
tom@zipit2:~$ ./hello.pl
Hello there World
tom@zipit2:~$
TopFinishing Up
Ok, the object lesson here is how we can easily add what we want included into the final
image. It is not necessary to club, or beat, OE into submission, just learn how it
is supposed to work and follow the rules.
Before you move on to the next section, you may want to comment out those
MACHINE_ESSENTIAL_EXTRA_RDEPENDS we just added. You may decide not to, that is fine
as well. These were added to illustrate something that will be useful
in the next section of building the GUI images.