Here is a list of issues that will lead at a moment or another to a failure about cross compilation with the current ports tree:
Clang is a cross-compiler out of the box. The desired target triple must be specified, for example -triple arm-unknown-freebsd. You may also want to explicitly add some other flags, such as -march and so on. If you are using clang's internal assembler, then you can generate .o files natively, however you will still currently need a linker specially compiled for your target platform. Ideally, the whole of binutils will need to be built for the target - clang should automatically use {triple}-ld and {triple}-as if it exists, in preference to the normal ld and as.
Ports' {BUILD,EXTRACT,FETCH,PATCH,PKG}_DEPENDS by convention use ${progname}:categ/portname to identify dependency on a particular tool that must be executable within the corresponding build stage. These may be useful in determining which dependencies must be built for the host.
.if defined(PORT_TARGET_ARCH)
.if defined(GNU_CONFIGURE)
CONFIGURE_TARGET=${PORT_TARGET_ARCH}-freebsd
CONFIGURE_ARGS+=--target ${PORT_TARGET_ARCH}-freebsd --host ${PORT_TARGET_ARCH}-freebsd
.else
__Y=${PORT_TARGET_ARCH}-freebsd-
AR = ${__Y}ar
RANLIB = ${__Y}ranlib
AS = ${__Y}as
NO_CFT=1
CXX = ${__Y}cxx
CC = ${__Y}cc
CPP = ${__Y}cpp
#FC = ${__Y}f77 # notyet
LD = ${__Y}ld
OBJC = ${__Y}cc
.endif
.endif
http://blog.chris.tylers.info/index.php?/archives/249-Fedora-ARM-PandaStack.html (broken)
Use lots of target hardware in a cluster connected to a NFS server. Farm out the work across the cluster.
mav@ has made a SheevaPlug available online for building arm packages. It uses NFS storage but the networking is currently suffering performance problems.
Hardware from the NLM multi-threaded MIPS boxes in the Netperf cluster might be available for trying the same sort of thing.
Another possibility is to run the compiler on the host, but everything else in the emulator. There are a few ways of doing this. The simplest is to use distcc, but that still does the preprocessing in the emulator, which is not ideal, but faster than doing the entire compile there. If they share a filesystem (e.g. an NFS server in the host) then you could probably replace cc, c++, and so on in the emulated environment with shell scripts that ran the cross compiler on the host (just needs to pass the arguments down a socket, so a wrapper around netcat would probably work).
This idea comes from the paper: http://www.mewburn.net/luke/papers/build.sh.pdf
Krister Walfridsson has proposed building the packages natively in an emulator, using optimizations such as only emulating user-mode, and capturing system calls and running those natively (after manipulating the arguments). An enhancement to that is to detect if an emulated program is gcc (for example), and invoking the host's cross-compiler natively for that case. The initial progress looks very promising, with an arm emulator compiling six times faster than the native platform.
QEMU user mode information:
http://qemu.weilnetz.de/qemu-tech.html#User-emulation-specific-details
http://static.usenix.org/event/usenix05/tech/freenix/full_papers/bellard/bellard.pdf
QEMU supports user mode emulation in order to run a Linux process compiled for one target CPU on another CPU. At the CPU level, user mode emulation is just a subset of the full system emulation. No MMU simulation is done because QEMU supposes the user memory mappings are handled by the host OS. QEMU includes a generic Linux system call converter to handle endianness issues and 32/64 bit conversions. Because QEMU supports exceptions, it emulates the target signals exactly. Each target thread is run in one host thread.
Endian independent (EI) UFS:
Using the following method (proposed by NgieCooper) should permit cross-building with build systems that don't work within “sane” constraints like autoconf does.
This process will be executed for everything that's a build tool for the target package ({BUILD,EXTRACT,FETCH,PATCH,PKG}_DEPENDS).
This process will be executed for everything that's a runtime package for the target package ({LIB,RUN,PKG}_DEPENDS).