Cross-compiling tools package guidelines

From ArchWiki
Revision as of 01:27, 28 August 2012 by AlexanderR (Talk | contribs) (elaborated on some topics, almost ready for adding to series)

Jump to: navigation, search


Tip: As alternative for creation of cross-compiler packages you could use crosstool-ng and create you own toolchain in fully automated way. crosstool-ng can be find on crosstool-ngAUR
.

Important note

This page describes new way of doing things, inspired by follwing packages in [community]:

Version compatibility

Warning: Using incompatible version of packages for toolchain compilation leads to inevitable failures. By default consider all versions incompatible.

Following strategies allows to select compatible vesions of gcc, binutils, kernel and C library:

  • General rules:
    • there is correlation between gcc and binutils releases, use simultaneously released versions;
    • it is better to use latest kernel headers to compile libc but use --enable-kernel switch (specific to glibc, other C libraries may use different conventions) to enforce work on older kernels;
  • Official repositories: you may have to apply additional fixes and hacks, but versions used by Arch Linux (or it's architecture-specific forks) most probably can be made to work together;
  • Software documentation: all GNU software have README and NEWS files, documenting things like minimal required versions of dependencies;
  • Other distributions: they too do cross-compilation
    • Gentoo crossdev lists some working combinations.
  • http://cross-lfs.org covers steps, necessary for

Building a Cross Compiler

The general approach to building a cross compiler is:

  1. binutils: Build a cross-binutils, which links and processes for the target architecture
  2. headers: Install a set of C library and kernel headers for the target architecture
    1. use linux-api-headers as reference and pass ARCH=target-architecture to make
    2. create libc headers package (process for Glibc is described here)
  3. gcc-stage-1: Build a basic (stage 1) gcc cross-compiler. This will be used to compile the C library. It will be unable to build anything almost else (because it can't link against the C library it doesn't have).
  4. libc: Build the cross-compiled C library (using the stage 1 cross compiler).
  5. gcc-stage-2: Build a full (stage 2) C cross-compiler

The source of the headers and libc will vary across platforms.

Tip: Exact procedure varies greatly, depending on your needs. For example, if you want to create "clone" of Arch Linux system with same versions of kernel and glibc, you can skip building headers and pass --with-build-sysroot=/ to configure.

Package naming

The package name shall not be prefixed with the word cross-, and shall consist of architecture triplet and the package name.

Thus, cross GCC for MIPS shall be mips-gcc.

File Placement

Latest versions of gcc and binutils use non-conflicting paths for sysroot and libraries. Executables shall be placed into /usr/bin/, to prevent conflicts here, prefix all of them with architecture name.

Typically, ./configure would have at least following parameters:

_target=<your-target> # e.g. i686-pc-mingw32
_sysroot=/usr/lib/${_target}
...
./configure \
    --prefix=${_sysroot} --sysroot=${_sysroot} \
    --bindir=/usr/bin

Example

This is PKGBUILD for binutils for MinGW. Things worth noticing are:

  • specifying root directory of the cross-environment
  • usage of ${_pkgname}, ${_target} and ${_sysroot} variables to make the code more readable
  • removal of the duplicated/conflicting files
# Maintainer: Allan McRae <allan@archlinux.org>

# cross toolchain build order: binutils, headers, gcc (pass 1), w32api, mingwrt, gcc (pass 2)

_target=i686-pc-mingw32
_sysroot=/usr/lib/cross-${_target}

pkgname=cross-${_target}-binutils
_pkgname=binutils
pkgver=2.19.1
pkgrel=1
pkgdesc="MinGW Windows binutils"
arch=('i686' 'x86_64')
url="http://www.gnu.org/software/binutils/"
license=('GPL')
depends=('glibc>=2.10.1' 'zlib')
options=('!libtool' '!distcc' '!ccache')
source=(http://ftp.gnu.org/gnu/${_pkgname}/${_pkgname}-${pkgver}.tar.bz2)
md5sums=('09a8c5821a2dfdbb20665bc0bd680791')

build() {
  cd ${srcdir}/${_pkgname}-${pkgver}
  mkdir build && cd build

  ../configure --prefix=${_sysroot} --bindir=/usr/bin \
    --with-sysroot=${_sysroot} \
    --build=$CHOST --host=$CHOST --target=${_target} \
    --with-gcc --with-gnu-as --with-gnu-ld \
    --enable-shared --without-included-gettext \
    --disable-nls --disable-debug --disable-win32-registry
  make || return 1
  make DESTDIR=${pkgdir}/ install || return 1
  
  # clean-up cross compiler root
  rm -r ${pkgdir}/${_sysroot}/{info,man}
}

Hows and whys

Template:FAQ

Template:FAQ

See also

http://wiki.osdev.org/GCC_Cross-Compiler