wiki:CrossCompiler/DebianPackage

Cross-building a debian package

(See the CrossCompiler/Examples tutorials)

Create the package

You may want to create a debian package that can build on several architectures.

First, you should work on sources from a dist tarball:

$ cd mySoftware
$ ./autogen.sh || ./configure  #this runs either autogen or configure
$ make dist

This will result in creating a mySoftware-x.y.z.tar.gz (where x.y.z is the version number) move it somewhere, rename it to mySoftware_x.y.z.orig.tar.gz and change directory to the directory where you moved it, then uncompress it:

$ mv mySoftware-x.y.z.tar.gz /tmp/mySoftware_x.y.z.orig.tar.gz # Will rename the tarball and move it in /tmp
$ tar xvzf mySoftware_x.y.z.orig.tar.gz
$ cd /tmp/mySoftware-x.y.z

Having a mySoftware_x.y.z.orig.tar.gz tarball along with the sources allows dpkg to generate the differences between the sources and the to-be-created debian package.

Create the debian packaging meta-data

There are many ways to create a Debian package, but here we focus on the debhelper method. Make sure you are in the directory containing the source code, and then run:

$ dh_make --createorig

Then, delete debian/*.(ex|EX) and edit the files in debian/ (see the  debian packaging guide for more information)

An helper script, trunk/packages/mkdebpackaging.sh does that, and some more.

Forcing LDFLAGS (in debian/rules)

Modify and complete the file like this:

ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE)
CROSS_CFLAGS=-I/usr/$(DEB_HOST_GNU_TYPE)/include -I/usr/$(DEB_HOST_GNU_TYPE)/usr/include
LDFLAGS=-L/usr/$(DEB_HOST_GNU_TYPE)/lib -L/usr/$(DEB_HOST_GNU_TYPE)/usr/lib
MAKE_LDFLAGS=-inst-prefix-dir /usr/$(DEB_HOST_GNU_TYPE) -Wl,-rpath-link /usr/$(DEB_HOST_GNU_TYPE)/lib -Wl,-rpath-link /usr/$(DEB_HOST_GNU_TYPE)/usr/lib
DH_SHLIBDEPS=dh_shlibdeps -l/usr/$(DEB_HOST_GNU_TYPE)/lib:/usr/$(DEB_HOST_GNU_TYPE)/usr/lib -- --ignore-missing-info
else
CROSS= --build $(DEB_BUILD_GNU_TYPE)
DH_SHLIBDEPS=dh_shlibdeps
endif

(this goes typically between #export DH_VERBOSE=1 and config.status: configure)

Listing dependencies with dh_shlibdeps needs extra attention. Therefore, you will also have to replace dh_shlibdeps by $(DH_SHLIBDEPS) at the bottom of the script.

Then, tell ./configure about the LDFLAGS:

./configure [...] $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS) $(CROSS_CFLAGS)" LDFLAGS="-Wl,-z,defs $(LDFLAGS)"

and make too:

$(MAKE) [...] LDFLAGS="$(MAKE_LDFLAGS) $(LDFLAGS)"

ltmain.sh

If your package uses libtool:

Around line 2784:

esac
             fi
             test -f "$inst_prefix_dir$add" && add="$inst_prefix_dir$add" # add this line
             if test "$linkmode" = prog; then

That's it. You also may want to update debian/changelog (take care of the format)

Build the package

You need to build the package either as the root user:

# dpkg-buildpackage -us -uc -aarmel

or using fakeroot like this:

$ dpkg-buildpackage -rfakeroot -us -uc -aarmel

if you want to build it for the armel architecture for example (like the Openmoko phone). Make sure you have set the pkg-config environment variables accordingly (see Compiling) ; you may also have to export CPATH=/usr/arm-linux-gnueabi/usr/include (already done by default).

It is easier to integrate your work in hackable:1, within the packages.txt file, and then use the package.sh script.

How to install a missing package

If ./configure complains about missing packages. This is because pkg-config can't find them. You should install them under /usr/<target architecture>.

For instance, if you miss package "mydependency", find the debian package for the target architecture (say, armel) and proceed like this:

# dpkg-deb -x package_X.x_armel.deb /usr/arm-linux-gnueabi/

if you want to cross-build for arm-linux-gnueabi

Alternatively you could install via apt-cross for upstream packages (Warning, it is not 100% working yet. We are discussing this issue and others with emdebian). This will resolve, build and install the missing dependencies of the package requested to be installed for you:

# apt-cross -a armel -v -i <your_package>

To install packages build locally via ./package.sh, use dpkg-cross :

# dpkg-cross -a armel -i <your_package>.deb

then resolve system dependencies missing with apt-cross as seen above.

Known problems

Impossible to cross-compile packages

It is not trivial to create Debian (and therefore hackable:1) packages for a different architecture than the native one. See  libmokoui2,  wifig and  neod for examples.

You may also take a look at CrossCompiler/Examples.