Bering-uClibc 5.x - Developer Guide - Building a Package
Building a Package | ||
---|---|---|
Prev | Bering-uClibc 5.x - Developer Guide | Next |
Contents
Introduction
Buildpacket is a tool used to create .lrp Packages. When creating Packages manually, there are many things that can go wrong (forgetting to copy a file, wrong file permissions) and buildpacket tries to eliminate those problems. It uses a Package definition in XML format to specify which files to copy (and what permissions they should have). It also automatically generates the lrcfg files which describe the contents of the Package to the apkg tool.
Most LEAF development tasks are best performed as a non-root user but Buildpacket has to change ownership of some files, which only root can do. Therefore, it is advised to use "fakeroot" when running the Buildpacket script.
Since it is not obvious at first, a little clarification: buildpacket creates .lrp Packages (packagename.lrp
) that are defined in buildtool setups (unfortunately, those are sometimes also called packages). These two need not have the same name: for example, there is a buildtool setup for lcd4linux which has a package definition for buildpacket for a package called lcd4linx.lrp
(missing the "u" since for Bering-uClibc 3.x and earlier Package names were restricted to the 8.3 MS-DOS filename format).
Furthermore, one buildtool setup can contain definitions for more than one .lrp Package - the openssl buildtool setup, for example, contains definitions for libssl.lrp
and openssl.lrp
.
It is important to not confuse those two notions of "packages". The reason this is a little confusing is mainly historical - plus the fact that one source tarball can produce the binaries for several Packages. This problem is common to other packaging systems (and the tools that generate the packages) - one "source rpm" for can create lots of individual rpm files, depending on how modular the packagers wanted to make things.
In general, within this Wiki, the term "Package" (with a capital P) is used to refer to a .lrp Package which can be installed onto a LEAF system, rather than the buildtool setup or "source package".
Step by step guide to setting up the configuration for hdsupp.lrp
In this section, we will finish up the hdsupp package, so buildpacket will be able to create an lrp-file from the sources buildtool created. To do this, open repo/hdsupp/buildtool.cfg
and append the following text:
<Package> <hdsupp> Version = 1.0 Revision = 1 License = GPL-2.0 Help <<EOF Tools to be create a bootable partition from within Bering-uClibc. The procedure to get a plain syslinux partition (if you want to use lilo, you're on your own) is something like this: 1. make sure your Bering install actually supports your harddrive (i.e. insert the appropriate modules) 2. Run fdisk to create the partitions. I usually create an empty DOS partition table (using the 'o' command) create a primary partition, make that bootable (using the 'a' command) 3. Run mkfs.msdos on the newly created partition (e.g. mkfs.msdos /dev/hda1) 4. Copy the MBR to the drive using (assuming your harddrive is /dev/hda) dd if=/usr/sbin/mbr.bin of=/dev/hda bs=512 count=1 5. Mount the drive and copy the bering files onto the drive (please read the bering users guide, section "Booting from an IDE device", it has some vital info for that part of the process) Remember to change the 'boot' and 'PKGPATH' to point to your harddrive. 6. run syslinux (e.g. syslinux /dev/hda1) This is usually the last thing I do (after unmounting the partition again, of course), because that way, I can simply copy everything from the floppy without having to worry about leaving ldlinux.sys alone (since that gets overwritten with the correct version by running syslinux) EOF <Permissions> Files = 644 Directories = 755 </Permissions> <Owner> Files = root:root Directories = root:root </Owner> <DependsOn> Package = mtools </DependsOn> <Contents> <File> Source = sbin/fdisk Filename = usr/sbin/fdisk Type = binary Permissions = 755 </File> <File> Source = sbin/mkfs.minix Filename = usr/sbin/mkfs.minix Type = binary Permissions = 755 </File> <File> Source = sbin/mkfs.msdos Filename = usr/sbin/mkfs.msdos Type = binary Permissions = 755 </File> <File> Source = usr/sbin/syslinux Filename = usr/sbin/syslinux Type = binary Permissions = 755 </File> <File> Source = usr/sbin/mbr.bin Filename = usr/sbin/mbr.bin Type = binary # We don't neet to specify permissions here, # since the default 644 will do just fine </File> </Contents> </hdsupp> </Package>
buildtool.cfg
The configuration for this script is integrated into the buildtool.cfg
file that controls the download of the sources. It resides in its own block called "Package".
Sample (comments below):
<EnvVars> PKG_NAME = $Packet </EnvVars> # # We can't use the variable $Package because it conflict with the <Package> node. PacketVersion = 1.0 PacketRevision = 1 Packet = foo <Package> <$(Packet)_1> Version = $PacketVersion Revision = $PacketRevision License = GPL-2.0 Help <<EOF Some Sample package See http://foo.bar.org/ Requires: <none> LRP package by __PACKAGER__, __BUILDDATE__ EOF PackageType = lrp PackageName = $Packet <Permissions> Files = 644 Directories = 755 </Permissions> <Owner> Files = root:root Directories = root:root </Owner> <DependsOn> Package = one Package = two </DependsOn> <Contents> ?include <common.cfg> <File> Filename = etc/init.d/$Packet Description = $Packet daemon init file Type = conf Type = local # because no ConfFile parameter was given, entry will end up in /var/lib/lrpkg/foo.conf </File> <File> Filename = etc/$Packet Type = list Type = local </File> <File> Filename = etc/$(Packet)/$(Packet).cfg Description = $(Packet) config file Type = conf ConfFile = $(Packet).bar # entry will end up in /var/lib/lrpkg/foo.bar.conf </File> <File> Source = usr/local/sbin/$(Packet).d Filename = usr/sbin/$(Packet).d Type = binary Permissions = 755 </File> </Contents> </$(Packet)_1> <anotherPackageHere> ... </anotherPackageHere> </Package>
Variables
Local Variables
You can defined local variables (like PacketVersion and PacketRevision in the example above) outside the <Package> block. Variable names are case insensitive.
The syntax is: variable = value
The variables can be used anywhere in the buildtool.cfg
file.
The variable will be replace by it's value when the buildtool.cfg
file is loaded.
The syntax to get the value of a variable is: $variable or $(variable)
If you need to have a variable not to be replace by it's value used the syntax: ${variable}
Environment Variables
You can defined environment variables in an <EnvVars> block (look in the example above). The syntax is the same as #Local Variables.
Environment variables is like local variables but will be export and define in the environment where the make command will be execute. So environment variables can be used in the buildtool.mk
file.
Includes
Since for some packages, there are a lot of common entries between package definitions within one buildtool.cfg
file (look at initrd
for an example) buildpacket supports include files, which contain all the common stuff.
Syntax is: ?include <file_to_be_included>
In the example above, the file common.cfg
(which must be declared as a file in buildtool.cfg
so it will be downloaded by buildtool) will be loaded by buildpacket, and its contents will be placed instead of the ?include line.
There is no limit on the number of times you include a single file, or on the total number of includes.
Include files may contain include directives themselves.
Version
The version of the source-code used to compile the package. If Version and Revision are omitted (completely omitted, not simply defined as an empty string), no packagename.version
file will be generated.
Use whatever version identification string is used by the upstream source-code distribution, assuming there is one. Can include letters as well as numbers, if required.
Revision
Revision of the Package (to distinguish different builds of the same source). Start at 1 and increment by 1 for each change. Start at 1 again when the Version changes.
Note: If neither Version nor Revision are specified in the config file (this means, the key does not exist - not that the value is simply left blank) no packagename.version
file will be generated. This is useful for packages that get their version from another package (like root.lrp
or etc.lrp
, which get their version info from initrd.lrp
).
License
The Open Source license which applies to the Package. See license.lrp
for more details.
The value needs to match the name of a file in directory repo/license/
(on the build host, or /var/lib/lrpkg/licenses/
once installed) which in turn is normally the license name specified by the Software Package Data Exchange.
Based on this variable being specified, a symbolic link /var/lib/lrpkg/packagename.license
is created, linking to the file containing the text of the license which applies. This is required for compliance with the terms and conditions of several Open Source licenses.
Add a new entry to license.lrp
if the license required for a Package is not currently included.
Permissions
Default permissions to give files/directories. Format is any valid input to the chmod command.
Owner
Default ownership given to the files/directories. Format is any valid input to the chown command.
DependsOn
List of Packages which should be automatically loaded at runtime to support the operation of this Package. Only the Package name should be specified, not the .lrp
file extension.
Typically includes any shared libraries required to run any executables present in the Package, and any non-standard command interpreters (for example perl in shorewall's buildtool.cfg
).
<DependsOn> Package = perl </DependsOn>
Only those Packages required directly to support the current Package should listed. For example, if Package A depends on Package B which depends on Package C there is no need to specify that A depends on B and C. The dependencies are processed recursively when the Packages are installed.
Note that this is different from "<Requires>" which specifies the Sources required to build a Package. "<DependsOn>" specifies the Packages required to execute a Package. A different label was chosen deliberately, to (try to) avoid confusion.
Packagename
For simple Packages, the name of the Package and the actual .lrp file are the same. There are cases though, where one needs to build several versions of the same Package (and therefore needs to create different .lrp files). One of those examples is initrd - there are several versions of the initrd package ("plain", one with ide support, one with usb support).
So to avoid a filename clash, we need to generate initrds of different names, while still making sure that internally, every package "thinks" it's name is initrd.lrp
This is where the packagename parameter comes in. If it is omitted, the package-name and the filename of the generated package will be the same, it will be the name of the XML tag, with the extension .lrp
appended
For those cases where we need different versions of the same package, the packagename parameter should be given the name that the package should "think" it has. For example:
<Package> <initrd> packageName = initrd # (redundant) other contents </initrd> <initrd_ide_cd> packageName = initrd other contents </initrd_ide_cd> <initrd_usb> packageName = initrd other contents </initrd_usb>
This would result in 3 packages being generated (initrd.lrp
, initrd_ide_cd.lrp
and initrd_usb.lrp
) but internally, all 3 packages would be defined as if their name was initrd.lrp
- which also means that one needs to rename initrd_usb.lrp
to initrd.lrp
before one can use it to boot from some USB stick.
Packagetype
All packages except initrd simply are gzip compressed tar archives. Initrd on the other hand is a gzip compressed cpio archive.
To be able to also generate initrd packages with buildpacket, the packagetype parameter has been added. It defaults to "lrp", which means that a standard tar.gz type package will be generated.
If one specifies "initrd" for the packagetype parameter, a gzip compressed cpio archive will be generated instead.
Obviously, this parameter is only useful if you are working on building customized initrd packages.
Help
Text to put into the .help file. If the .help file should only consist of a single line, you can simply define it as:
Help = Text for the help file
If you need more than one line (most likely you will), you can use the mechanism used in the example.
The following "tags" that will be replaced at build time are supported:
- __PACKAGER__ The name of the user who built the package (this is why you need to specify the packager on the command line).
- __BUILDDATE__ The date the package was created.
Contents
List of "File" blocks that define the contents of the package.
Note: Only the files that need special care like binaries or directories "owned" by the lrp need to be listed here - stuff that came from the skeleton file or the files automatically generated by the tool are added automatically (but if they need other permissions/ownership than the default, you still need to specify them - as "LIST", for example). A file can be of more than one type - in this case, simply specify more than one "Type = xxx" line.
File
Target filename (including relative path) that the link should point to (only used together with type=link)
Filename (including relative path) of the file in the package
Source relative (to buildtools staging-dir) path/filename to the file generated by buildtool. If source contains wildcards then the parameter "Filename" is assumed to be a directory.
Type specifies the how buildpacket should treat this file. Possible types are:
- binary - For files that are copied from the staging_dir of buildtool - not necessarily a binary formatted file
- Specify this in order to have the file included in the Package
.lrp
- Likely to be specified for every <File> entry
- Specify this in order to have the file included in the Package
- list - File (or pattern) to add to the
packagename.list
file - conf - File to add to
packagename.conf
. For files of this type, one can also add the parameter conffile. Normally, all conf-files are added to the file/var/lib/lrpkg/packagename.conf
. If one needs to put conf entries into a different file (needed for the etc package, for example), one can specify the name of the file (without extension) here.- Specify this in order to have files appear in the lrcfg menu for the Package
- If no files in a Package have "conf" specified the Package will not have an entry in the lrcfg Packages menu
- local - File to add to
packagename.local
(for partial backups). At this point only the type "I" (for including the file in the local backup) is supported, type "X" (for excluding a file from the local backup) is not.- Specify this in order to have the file(s) backed-up when the configuration is saved
- link - Specifies that this file is a (soft-) link that should be created during package creation. Filename specifies the name of the link (relative to the root dir). You MUST also specify Target (which tells buildpacket where the link should point to)
- device - Specifies a device entry (e.g.
/dev/console
) - Buildpacket creates this device with the mknod command. The device type, major and minor number are required.
<File> Filename = dev/console Type = device devtype = c major = 5 minor = 1 </File>
- directory - Filename specifies the name of a directory that should be created. Source is ignored. Only useful if you need to create empty directories in the package (if they weren't empty buildpacket would create them automatically anyway)
Note: You can use more than one type at the same time. For example, to specify that a file should be copied from the staging dir (making it a "binary") and is a configuration file and should be added to the packagename.local
file, you would specify:
<File> Filename = etc/sample.conf Description = Configuration file Type = binary Type = conf Type = local </File>
Note: In order to be able to generate the root.lrp
package, special handling of an an entry like
Filename = / Type = List
has been added. Normally, leading / in the filename are stripped, which would result in an empty entry in the list (which would in turn be ignored). To get around that, empty list-entries are replaced with ./ - which happens to be exactly what is needed to produce the correct root.list
file.
Note: You can also use wildcards. For example, for copying a list of files with a common prefix or suffix , you would specify:
<File> Filename = lib/iptables/ Source = lib/iptables/libipt*.so Type = binary Permissions = 755 </File>
But be careful with using wildcards - since buildpacket is doing some guessing here (it assumes that adding the file part from "Source" to the path specified in "Filename" will generate a pattern, that will match all files, copied into the archive). It will not work if there are wildcards in the path of "Source" - so "Source = foo/bar*/*.txt" will not work. Also, specifying wildcards in "Filename" will most likely not produce the desired results.
The reason why all this "guessing" is necessary, is that buildpacket needs to find the individual files, so it can apply the permissions/ownerships according to the specification.
Description - Only used for file type "conf" - specifies the description/help to be shown in the lrcfg menu.
- If not specified the filename is shown instead
Permissions - Specifies the permissions of this file if they're different from the default.
Config settings in buildtool.cfg
The following items can be set in buildtool.cfg
- gzip_options: should simply be "-9", but may also contain any other options you want to add when gzip is executed.
- packager: Name (and optionally email address) of the person using this buildtool/buildpacket installation. By setting this option, one doesn't need to supply the packager parameter on the command line
- lrpowner and lrpgroup: If you must run buildpacket as root (because fakeroot doesn't work on your plattform, for example), you can specify the username/groupname that should own the generated lrp package - so you don't have files owned by "root:root" in the packages directory
- mountpoint: The mountpoint where the minix-image should be mounted (used for initrd, for example). Default is /mnt/loop
Creating packages
Usage:
buildpacket.pl --package=packagename --packager=name_of_packager [--target=packagefile] [-lrp=existing.lrp] [-all] [--verbose]
Example:
fakeroot ./buildpacket.pl --package=zlip --packager="Martin Hejl" --verbose
Caution: Currently, buildpacket does not check whether the sources have already been installed. This is something that will be done later on, when buildpacket is more integrated into builtool
Options
- --package
- The name of the package you compiled using fakeroot ./buildtool.pl build packagename
- --packager
- The name of the user who created the package. The string you enter here is added to the .help file (if the help section contains the __PACKAGER__ tag)
- --target
- For packages that create more than one lrp-file (like openssh), this specifies which lrp to create. If this option is omitted, the value of --package is used
- --lrp
- If you already have an existing lrp file and you want to migrate your configuration to the new package, specify the lrp file here and it will be integrated into the package (if the .cfg file is set up correctly, the config will be migrated, but all binaries will be replaced with the new versions). This needs more work (it's pretty crude at this point), probably the lck-scripts by Alex Rhomberg will be integrated/used to take care of this.
- --verbose
- Turns on verbose logging
- --all
- If a package definition specifies more than one package (like openssh, which produces ssh, sshd, sshkey and sftp), specifying --all instead of --target causes buildpacket to create all packages at once. This parameter defaults to yes (it's a leftover from previous versions of buildpacket) so it should no longer be used. If you only want to build one specific package for a given buildtool setup which defines several packages, you must specify --package and --target
Prev | Up | Next |