Difference between revisions of "Cross-compiling tools package guidelines"

From ArchWiki
Jump to: navigation, search
(clean up a bit before adding to *Guidelines series)
Line 1: Line 1:
 
[[Category:Package development]]
 
[[Category:Package development]]
  
{{out of date}}
+
__TOC__
  
== Hint ==
+
{{Tip|As alternative for creation of cross-compiler packages you could use [http://crosstool-ng.org/  crosstool-ng] and create you own toolchain in fully automated way. crosstool-ng can be find on {{AUR|crosstool-ng}}}}.
  
The idea of creating cross compiling tools packages seems to be abandoned. You could however use [http://crosstool-ng.org/  crosstool-ng] and complile you own toolchain easily. crosstool-ng can be find on [https://aur.archlinux.org/packages.php?O=0&K=crosstool&do_Search=Go AUR].
+
== Important note ==
 +
This page describes new way of doing things, inspired by follwing packages in {{Ic|[community]}}:
 +
*{{Pkg|mingw32-gcc}} and other packages from {{Ic|mingw32-*}} series
 +
*{{Pkg|arm-elf-gcc-base}} and other packages from {{Ic|arm-elf-*}} series
 +
*{{Pkg|arm-wince-cegcc-gcc}} and other packages from {{Ic|arm-wince-cegcc-*}} series
  
== Important ==
+
== Version compatibility ==
This page describes a proposal, not an accepted approach!
+
{{Warning|Using incompatible version of packages for cross 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 {{Ic|--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 / Arch Linux ARM most probably can be made to work together
 +
*Other distributions: they too do cross-compilation
 +
**Gentoo crossdev [http://en.gentoo-wiki.com/wiki/Crossdev#Known Working Architecture Matrix|lists some working combinations]
  
 
==Building a Cross Compiler==
 
==Building a Cross Compiler==
Line 20: Line 32:
 
The source of the headers and libc will vary across platforms.
 
The source of the headers and libc will vary across platforms.
  
== Package Naming ==
+
<!--== Package naming ==
 
The package name shall be prefixed with the word '''cross-''', followed by architecture name and the package name itself shall come at the end.
 
The package name shall be prefixed with the word '''cross-''', followed by architecture name and the package name itself shall come at the end.
  
Thus, cross GCC for MIPS shall be '''cross-mips-gcc'''.
+
Thus, cross GCC for MIPS shall be '''cross-mips-gcc'''.-->
  
  

Revision as of 23:25, 27 August 2012


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 cross 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 / Arch Linux ARM most probably can be made to work together
  • Other distributions: they too do cross-compilation

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
  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. Can be built

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


File Placement

To prevent file conflicts, place everything into /usr/lib/cross-<target>. The only exception to this rule are executables, that shall be placed directly into /usr/bin/ (however, 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

Why not installing into /opt? There would be no need for fooling around with non-standard executable naming etc.?

Two reasons:
First, according to File Hierarchy Standard, these files just belong somewhere to /usr. Period.
Second, installing into /opt is a last measure when there is no other option.

What is that out-of-path executables thing?

This weird thing allows easier cross-compiling. Sometimes, project Makefiles do not use CC & co. variables and instead use gcc directly. If you just want to try to cross-compile such project, editing the Makefile could be a very lengthy operation. However, changing the $PATH to use "our" executables first is a very quick solution.
You would then run PATH=/usr/bin/cross/arch/:$PATH make instead of make.