Cross compile packages

This forum is for discussion about general software issues.

Cross compile packages

Postby muellni » Mon Sep 16, 2013 12:26 pm

I run arch on a SABRE Lite board using the Nitrogen6X-rootfs. Nice job so far, everything boots well!

Now I'd like to compile a package of my own software for the board from my host machine (x86_64).

The description at building-packages seems to compile directly on the device.

The description at distcc-cross-compiling is at least issueing the compile command from the $this->bbcode_second_pass_quote('', 'A')RM "master" device
.

Is there a way of cross-compiling arch packages, without touching the target device? Maybe using something like chroot or qemu?
muellni
 
Posts: 1
Joined: Mon Sep 16, 2013 12:13 pm

Re: Cross compile packages

Postby moonman » Mon Sep 16, 2013 1:00 pm

to use arm chroot you will need qemu, so there's no "OR". Qemu was tested before and some packages compiled broken so it doesn't work that well and is not recommended. So the best way is to use distcc.
Pogoplug V4 | GoFlex Home | Raspberry Pi 4 4GB | CuBox-i4 Pro | ClearFog | BeagleBone Black | Odroid U2 | Odroid C1 | Odroid XU4
-----------------------------------------------------------------------------------------------------------------------
[armv5] Updated U-Boot | [armv5] NAND Rescue System
moonman
Developer
 
Posts: 3387
Joined: Sat Jan 15, 2011 3:36 am

Re: Cross compile packages

Postby ebbix » Fri Sep 20, 2013 9:38 am

Well, if you use Arch Linux on your main machine (or in VirtualBox), you could use a modified makepkg command to cross compile using the official toolchain. This is what I use for my Kirkwood machines:
$this->bbcode_second_pass_code('', '#
# makepkg-arm.conf
# make sure this is in the same dir as makepkg-arm or adjust makepkg-arm
#
source /etc/makepkg.conf

CARCH="arm"
CHOST="arm-unknown-linux-gnueabi"

export PATH='/usr/local/toolchain/arm-unknown-linux-gnueabi-prefixed/bin':${PATH}
export ARCH='arm'
export CROSS_COMPILE='arm-unknown-linux-gnueabi-'

#-- Compiler and Linker Flags
# -march (or -mcpu) builds exclusively for an architecture
# -mtune optimizes for an architecture, but builds for whole processor family
CPPFLAGS="-D_FORTIFY_SOURCE=2"
CFLAGS="-march=armv5te -mtune=xscale -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"
CXXFLAGS="-march=armv5te -mtune=xscale -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"
#-- Make Flags: change this for DistCC/SMP systems
MAKEFLAGS="-j5"
#-- Debugging flags
DEBUG_CFLAGS="-g -fvar-tracking-assignments"
DEBUG_CXXFLAGS="-g -fvar-tracking-assignments"

# vim: set ft=sh ts=2 sw=2 et:
')
$this->bbcode_second_pass_code('', '#!/bin/bash
# makepkg-arm script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
makepkg --config "$DIR/makepkg-arm.conf" "$@"
')
Note the -march=armv5te -mtune=xscale flags for Kirkwood/XScale cpus (used gcc build does not support marvell-f, so nearest "relative" xscale is used)
/usr/local/toolchain/arm-unknown-linux-gnueabi-prefixed/bin comes from the official cross compiling toolchain, but every command is prefixed (no gcc command, only armv5tel-unknown-linux-gnueabi-gcc and arm-unknown-linux-gnueabi-gcc).
You can then run makepkg-arm to cross-compile a package that supports cross-compiling, i.e. uses the prefixed toolchain. (Tested to work with linux-kirkwood)
If your software does not support cross-compiling, then you could use a toolchain that does not have prefixed bintools, so that gcc would point at arm-unknown-linux-gnueabi-gcc instead. This works for packages that do not compile some script to be run during compilation (therefore it doesn't work for kernels, but I successfully compiled some other packages with this method). I have a script called makepkg-arm-hardcore for this.
ebbix
 
Posts: 48
Joined: Fri Aug 10, 2012 1:55 pm

Re: Cross compile packages

Postby WarheadsSE » Fri Sep 20, 2013 3:14 pm

Will it link against x86 binary packages dependencies? What about dependency installation?
Core Developer
Remember: Arch Linux ARM is entirely community donation supported!
WarheadsSE
Developer
 
Posts: 6807
Joined: Mon Oct 18, 2010 2:12 pm

Re: Cross compile packages

Postby ebbix » Sat Sep 21, 2013 6:35 pm

Damn, forgot to mention that.
This will not link correctly against required libraries (other than glibc and standard libraries) as the toolchain can only link against libraries found in arm-unknown-linux-gnueabi/sysroot/lib. So you have to be careful when your software has dependencies.
Standard libraries work though:
$this->bbcode_second_pass_code('', '$ ldd /usr/bin/unrar
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb6e28000)
libm.so.6 => /usr/lib/libm.so.6 (0xb6d87000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0xb6d60000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0xb6d40000)
libc.so.6 => /usr/lib/libc.so.6 (0xb6c12000)
/lib/ld-linux.so.3 (0xb6efc000)')
Dependencies and makedepends have to be installed on the host, no matter if they're required for building on the host or not...
And if tools that produce architecture-specific output are required (for example gcc-objc compiler, which is not included in the toolchain), then you can't use this approach. Other things as for example bc are fine though.
Until now I've been using this method to compile linux-kirkwood-dt (using prefixed toolchain), dtc and unrar (using non-prefixed toolchain) which have no dependencies to link against.
So long story short: at the moment this approach only works if you don't have libraries other than stdlibs to link against.

EDIT:
Okay, I've done some further testing. unzip was the first interesting package I found. It has only one dependency (bzip2) which it links against. With a clean toolchain (non-prefixed), it didn't build due to missing header file bzlib.h.
I then populated the toolchain's sysroot (/usr/local/arm-unknown-linux-gnueabi/sysroot) with all the files in /usr/include and /usr/lib from the current bzip2 package and tried another makepkg-run. It worked and linked against the correct libraries, the resulting binaries work perfectly on the target system. However, the makefile could still be badly written so that it won't cross-compile properly.
This is no convenient method (maybe a patched pacman could automate this? pass depends array and sysroot gets populated), but if you only need to compile some packages over and over again, then this could be an alternative. And if your package doesn't have any special dependencies, then this is definitively a nice method. My experience in compiling the kernel is: approx. 6 hours on the device, 2 hours using distcc, < 10 minutes completely cross-compiling (Core i5 2500, -j5).

EDIT²:
Turns out pacman is really the best package manager (it was a very good choice to switch from Fedora), it was very simple to tune it to my cross-compiling needs.
Setting its root and other dirs to toolchain sysroot and subdirs and using a modified config through a wrapper script, pacman can simply install all the needed dependencies (pacman-arm -Sydd dep1 dep2) without any further dependency resolving since only header files and shared objects are needed anyway. This makes the whole process relatively simple. I can provide additional information if anyone is interested.
However, even now some limitations remain. Host needs all dependencies and build-dependencies installed, too. And if any build-dependency tries to modify binaries or something, then all will almost definitively fail. And if the Makefile does crazy things, then cross-compiling might fail. I think I'll do some further research, refine this method and maybe write a complete guide for those interested.
ebbix
 
Posts: 48
Joined: Fri Aug 10, 2012 1:55 pm


Return to General

Who is online

Users browsing this forum: No registered users and 15 guests