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.
