@ 21 Apr 09

Crosscompilation and debian packaging for Hackable:1

This page is a minimalistic howto for creating/preparing debian packages for crosscompilation.
It focuses on the use of Hackable:1’s developement environnement, but tips and tricks should be usefull for other crosscompilation envs, particularly based on the emdebian toolchain (as Hackable:1 uses it).

Development environnement

I'm using the i386 development environnement distributed by Hackable:1.
I run it as a Xen domU. (see this howto to install the environnement on a NetBSD dom0here for a more generalist artice on Xen on NetBSD)

It comes with a crosscompiler for the ARM EABI target (corresponding to the Openmoko FreeRunner, or other ARM based devices such as Sharp Zauriis and Nokia Nxx0).

Setting up

I assume you just installed the development environnement (virtualization, …).

Here are steps you should follow:

  • create a simple user
  • upload its SSH public key
  • edit ~/.bashrc

     PKG_CONFIG_LIBDIR="/usr/arm-linux-gnueabi/usr/lib/pkgconfig:/usr/arm-linux-gnueabi/usr/share/pkgconfig"  
     PKG_CONFIG_SYSROOT_DIR="/usr/arm-linux-gnueabi"   
     export PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR   
     
  • get the sources

     svn co svn://trac.hackable1.org/hackable1/ --username=myusername  
     
  • build and install pkg-config version 0.23

     cd /path/to/sources/packages  
     ./package.sh pkg-config  
     dpkg -i pkg-config/pkg-config*deb  
     

Packaging

go into the source dir. the directory name should be something like “software-X.x”, X.x being the version number.

I recommend you to copy the source dir to a working dir.
If using Hackable:1 (or another) svn repo, export the data:

     svn export src/category/whateva /tmp/whateva-X.x  
 

Then, cd that directory.

Create the debian packaging sheme:

     dh_make -e myname@mymailprovider.net --createorig  
 

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

debian/rules for croscompilation

Here are a few tricks about crosscompilation and debian’s packaging script, debian/rules.

Forcing LDFLAGS

Khorben found how to sucessfully crosscompile a library by forcing LDFLAGS and patching libtool’s main script (see library + libtool).

You should add special flags for crosscompilation in the conditionnal block found in debian/rules :

 ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) 
   CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE) 
   LDFLAGS=-L/usr/$(DEB_HOST_GNU_TYPE)/lib -L/usr/$(DEB_HOST_GNU_TYPE)/usr/lib         # add this
 else 
   CROSS= --build $(DEB_BUILD_GNU_TYPE) 
   DH_STRIP=dh_strip                               # add this
   DH_SHLIBDEPS=dh_shlibdeps                       # add this
 endif 
 

We can’t strip and find dependancies with shlibdeps for crosscompiled softwares (for now, anyway).
So replace dh_strip and dh_shlibdeps by $(DH_STRIP) and $(DH_SHLIBDEPS) at the bottom of the script.

Then, tell configure and/or make about the LDFLAGS:

 ./configure [...] LDFLAGS="[...] $(LDFLAGS)"  
     ...
 $(MAKE) [...] LDFLAGS="[...] $(LDFLAGS)"  
 

library + libtool

If the software you're packaging is a library, you may have to proceed that step:

  • edit ltmain.sh, around line 2786:

     test -n "$add" && compile_deplibs="$add $compile_deplibs" 
     
    else
     test -f "$inst_prefix_dir$add" && add="$inst_prefix_dir$add" # add this
     test -n "$add_dir" && deplibs="$add_dir $deplibs" 
     test -n "$add" && deplibs="$add $deplibs" 
     
  • edit debian/rules, and tell configure about libtool parameters:

    ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) CROSS= —build $(DEB_BUILD_GNU_TYPE) —host $(DEB_HOST_GNU_TYPE) LDFLAGS=-inst-prefix-dir /usr/$(DEB_HOST_GNU_TYPE) -L/usr/$(DEB_HOST_GNU_TYPE)/lib -L/usr/$(DEB_HOST_GNU_TYPE)/usr/lib # add inst-prefix-dir
    else CROSS= —build $(DEB_BUILD_GNU_TYPE)

     $(MAKE) LDFLAGS="$(LDFLAGS)"    
     

binary executable, ld conplains about “lib foo not found”

If you get something like :

 /usr/lib/gcc/arm-linux-gnueabi/4.3.2/../../../../arm-linux-gnueabi/bin/ld: warning: libidn.so.11, needed by /usr/arm-linux-gnueabi/usr/lib/libcurl.so, not found (try using -rpath or -rpath-link)
 /usr/lib/gcc/arm-linux-gnueabi/4.3.2/../../../../arm-linux-gnueabi/bin/ld: warning: libssh2.so.1, needed by /usr/arm-linux-gnueabi/usr/lib/libcurl.so, not found (try using -rpath or -rpath-link)
 /usr/lib/gcc/arm-linux-gnueabi/4.3.2/../../../../arm-linux-gnueabi/bin/ld: warning: liblber-2.4.so.2, needed by /usr/arm-linux-gnueabi/usr/lib/libcurl.so, not found (try using -rpath or -rpath-link)
 

You should add rpath-link parameters for gcc. rpath-link tells gcc where ld should find the libraries for linking (rpath for finding libraries at execution)

Edit debian/rules and add rpath-linking parameters to the ‘make’ instruction:

 ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) 
   CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE) 
   LDFLAGS=-inst-prefix-dir /usr/$(DEB_HOST_GNU_TYPE) -L/usr/$(DEB_HOST_GNU_TYPE)/lib -L/usr/$(DEB_HOST_GNU_TYPE)/usr/lib
   MAKE_LDFLAGS=-Wl,-rpath-link /usr/$(DEB_HOST_GNU_TYPE)/lib -Wl,-rpath-link /usr/$(DEB_HOST_GNU_TYPE)/usr/lib   # add this  
 else 
 
 ...
 
     $(MAKE) [...] LDFLAGS="$(LDFLAGS) $(MAKE_LDFLAGS)"
 

that’s good :)

Using dpkg-buildpackage, you should now be able to build a package for armel:

 dpkg-buildpackage -us -uc -aarmel  
 

If not, see this page, about the problems and fixes for the cross compiling environnement.

References