Bering-uClibc 5.x - Developer Guide - Building a Package

From bering-uClibc
Revision as of 14:17, 14 April 2016 by Kapeka (Talk | contribs) (DependsOn - add example)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Building a Package
Prev Bering-uClibc 5.x - Developer Guide Next


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
  • 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