Emdebian Developer Guide

This is intended to provide tips and status information on the emdebianisation of Debian packages, problems encountered, solutions found and details of problematic packages. In due course, the advice here will be distilled into a dedicated Developer Guide and into the currently unformed Emdebian Policy documentation.

Anything that expands or clarifies issues in the emdebian-tools manpages can also be added here.

See also EmdebianQuickStart and ["Embedded_Debian"].

Cache Files

Packages consisting of compiled C code and using the autotools can support a cache file of values to help the ./configure script to identify settings for the target that differ from the architecture performing the build. Cache files can also be used to provide the answer when letting ./configure calculate the result would end in failure. Typically, this is due to ./configure trying to compile a test program on the build architecture using the target compiler - resulting in trying to run an arm binary on, say, amd64. To prevent such disasters, the value that the test program is trying to calculate can be provided in a cache file and autotools will skip the test program.

Currently, values for these cache files need to be elucidated the hard way: Let the build fail, work out where it failed, find the cache variable that would prevent the failing code from being run and then look up the value for that variable in the build logs of the native build in Debian.

./configure --cache-file=$(DEB_HOST_GNU_TYPE).cache

emdebuild protects the cache file so that the entered values are retained for the patch.

dpkg-gencontrol: error

Packages that use CDBS handle emlocale automatically. Packages that use debhelper need minor tweaks to ensure that the new packages created for the translation files get populated correctly. The problem comes with something like a rootfs where packages use the dpkg commands directly. To create and populate the translation packages, manual editing of debian/rules is necessary.

You need to add a clean: rule and a loop to build:

e.g. for diff (source package name diffutils), the loop for the build target consists of:

srcpkg=diffutils \
POFILES=`cd po && ls *.po | sed -e 's/\.po$$//'` ; \
for po in $$POFILES; do \
        TMPPO=`basename $$po | cut -f1 -d.` ; \
        TMPPKG=`echo $$TMPPO | tr '_@A-Z' '-+a-z'` ; \
        install -d debian/$$srcpkg-locale-$$TMPPKG/DEBIAN ; \
        install -d debian/$$srcpkg-locale-$$TMPPKG/usr/share/locale/$$TMPPO/LC_MESSAGES/ ; \
        install po/$$TMPPO.gmo debian/$$srcpkg-locale-$$TMPPKG/usr/share/locale/$$TMPPO/LC_MESSAGES/$$srcpkg.mo ; \
        dpkg-gencontrol -p$$srcpkg-locale-$$TMPPKG -Pdebian/$$srcpkg-locale-$$TMPPKG ; \
        dpkg --build debian/$$srcpkg-locale-$$TMPPKG .. ; \
done

Take care : your web browser could have added a line break in the long install line in the loop. The installation of po/bar.gmo into debian/foo/usr/share/locale/bar/LC_MESSAGES is a single line in debian/rules. Try reducing the font size or zoom level in your browser to get the correct line wrapping.

Remember to set the SOURCE package name in srcpkg and be very careful to retain all the double dollars.

Now remove the locale files from the parent package:

${RM} -r debian/tmp/usr/share/locale/

(Watch for packages that use foo-common or foo-data instead of tmp and update as appropriate.)

And finally, add a clean target:

${RM} -r debian/diffutils-locale-*

(Note here that $srcpkg is not available, you can move the variable elsewhere or just specify the source package name explicitly. The variable is only really to make it easy to migrate the loop between packages.)

Thanks to Julian Gilbey for the idea and fixes.

Adding cross-build detection

If debian/rules uses autotools yet does not use ---build and --host, the build process will probably fail to detect the cross-compiler. This is usually a bug in the upstream package. To fix, add:

DEB_HOST_GNU_TYPE=$(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE=$(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)

then add an extra pair of options to either confflags or ./configure

ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
else
CROSS=
endif

./configure $(CROSS) ...

or for packages that only use make but not configure:

ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
CROSS=CC=$(DEB_HOST_GNU_TYPE)-gcc
else
CROSS=
endif

Note that, for arm, the value of $(CROSS) is CC=arm-linux-gnu-gcc. There is no value $(CC) set in the above line, despite how it may appear from a C or perl perspective.

$(MAKE) $(CROSS) ...

Problematic packages

  1. perl-base Tries to run cross-built miniperlmain and possibly other generated binaries during make.

  2. openssl - ar is not passed the correct options when cross-building, despite the r tag being specified in the (perl based) Makefile.org. This halts the build when arm-linux-gnu-ar fails to get the r option that is used in a native build.

  3. libcap - compiles an internal program to generate a header file then tries to execute that file.

  4. apititude - needs to build in a chroot where the apt based dependencies can be handled correctly.

  5. gcc-??? - too complex for its own good. Frequent breakages in gcc are all the more problematic when Emdebian only needs two of the dozens of packages built from the gcc source: libgcc1 and libstdc++6. Mostly fixed now.

dh_shlibdeps errors

dh_shlibdeps
dpkg: /usr/arm-linux-gnu/lib/libacl.so.1 not found.
dpkg-shlibdeps: failure: dpkg --search gave error exit status 1
dh_shlibdeps: command returned error code 256

Check for the existence of the file within the build:

$ find . -name libacl.so.1
./debian/libacl1/lib/libacl.so.1
./libacl/.libs/libacl.so.1

and re-run dh_shlibdeps with the -l option:

$ dh_shlibdeps -l ./debian/libacl1/lib/
dpkg-shlibdeps.orig: warning: could not find any packages for libattr.so.1

Note that this example comes from libacl1 but the reference is to libattr - this gives you a clue that you need to use apt-cross - this is an [:EmdebianCrossPackages: Build-Cross-Depends] package.

$ sudo apt-cross -i libattr1

Then change the dh_shlibdeps rule in debian/rules to specify to look for the dependency information within the current build tree using -L and -l:

dh_shlibdeps -L libacl1 -l ./debian/libacl1/lib/

Incomplete build logs

Build failure logs are as useful as build completion logs but it is worth keeping these separate from the successful builds so an SVN branch can be used.

svn mkdir ../branches/fail1
mv emdebian*.patch ../branches/fail1
mv *.build ../branches/fail1
cd ../branches/fail1
svn add *
svn ci -m "failed build branch 1"

This leaves trunk clear so that if someone else fixes the build, your next svn update will apply cleanly.

Note that if this is an update to an existing Emdebian package, you should copy the patches and the build log then use svn revert to replace the last successful build data.

apt-cross

Until an equivalent to pbuilder is available for cross-building, the build host will need to install cross versions of the -dev packages required by the package being built. apt-cross -v -i libfoo-dev. Note that apt-cross does have problems with long dependency lists, particularly once debconf becomes involved. In this situation, until apt-cross is fixed, try just building the required libraries and then manually installing them.

Status Table

A [http://buildd.emdebian.org/svn/file/current/emdebian/trunk/logs/buildstatus buildstatus] script is available in SVN which will update your emdebian working directory and then count the number of packages where work has started, show how many patches are present for each and whether a build log was found. Build logs are present even if the build failed so this is only indicative of whether a build has been attempted. The final arbiter of whether a build was successful is the presence of a build log in SVN and the presence of a package in the Emdebian target repository. Unfortunately, I haven't yet found a quick way of checking SVN for build logs - using svn list took too long.


CategoryEmdebian