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

From ArchWiki
Jump to: navigation, search
(Hows and whys)
(Example now uses MinGW)
Line 20: Line 20:
  
 
== Example ==
 
== Example ==
This is PKGBUILD for GCC for MIPS.
+
This is PKGBUILD for binutils for MinGW.
 
Things worth noticing are:
 
Things worth noticing are:
*manually specifying where to find the '''as''' and '''ld''' binaries
+
*specifying root directory of the cross-environment
*usage of <code>${_pkgname}</code> and <code>${_target}</code> variables to make the code more readable
+
*usage of <code>${_pkgname}</code>, <code>${_target}</code> and <code>${_sysroot}</code> variables to make the code more readable
 
*removal of the duplicated/conflicting files
 
*removal of the duplicated/conflicting files
<pre># Contributor: Your name <your@email.somewhere.net>
+
<pre># Maintainer: Allan McRae <allan@archlinux.org>
pkgname=cross-mips-gcc
+
 
_pkgname=gcc
+
# cross toolchain build order: binutils, headers, gcc (pass 1), w32api, mingwrt, gcc (pass 2)
pkgver=4.3.2
+
 
pkgrel=2
+
_target=i686-pc-mingw32
pkgdesc="The GNU Compiler Collection for the MIPS architecture"
+
_sysroot=/usr/lib/cross-${_target}
url="http://www.gnu.org/software/binutils/"
+
 
 +
pkgname=cross-${_target}-binutils
 +
_pkgname=binutils
 +
pkgver=2.19.1
 +
pkgrel=1
 +
pkgdesc="MinGW Windows binutils"
 
arch=('i686' 'x86_64')
 
arch=('i686' 'x86_64')
 +
url="http://www.gnu.org/software/binutils/"
 
license=('GPL')
 
license=('GPL')
depends=('mpfr' 'sh' 'cross-mips-binutils')
+
depends=('glibc>=2.10.1' 'zlib')
options=('!ccache' '!distcc' '!emptydirs' '!libtool' '!strip')
+
options=('!libtool' '!distcc' '!ccache')
source=("ftp://ftp.gnu.org/gnu/gcc/gcc-${pkgver}/${_pkgname}-core-${pkgver}.tar.bz2")
+
source=(http://ftp.gnu.org/gnu/${_pkgname}/${_pkgname}-${pkgver}.tar.bz2)
md5sums=('dd8048b43d3d4e5595bcade47b9144c6')
+
md5sums=('09a8c5821a2dfdbb20665bc0bd680791')
_target="mipsel-linux-gnu"
+
  
 
build() {
 
build() {
cd ${srcdir}/${_pkgname}-${pkgver}
+
  cd ${srcdir}/${_pkgname}-${pkgver}
+
  mkdir build && cd build
./configure \
+
"--prefix=/usr" \
+
"--libexecdir=/usr/lib" \
+
"--program-prefix=${_target}-" \
+
"--target=${_target}" \
+
"--mandir=/usr/share/man" \
+
--without-headers \
+
--with-gnu-as --with-gnu-ld \
+
--with-as=/usr/bin/${_target}-as \
+
--with-ld=/usr/bin/${_target}-ld \
+
--disable-nls --disable-multilib --disable-shared \
+
--disable-libgcj --disable-threads --disable-tls \
+
--enable-languages=c || return 1
+
+
make all-gcc || return 1
+
+
make DESTDIR=${pkgdir} install-gcc || return 1
+
+
msg "Removing duplicit files..."
+
# remove these files as they are already in the system
+
# (with native gcc)
+
rm -Rf ${pkgdir}/usr/info
+
rm -f ${pkgdir}/usr/lib/libiberty.a
+
rm -Rf ${pkgdir}/usr/share/man
+
rm -Rf ${pkgdir}/usr/share/info
+
  
msg "Creating out-of-path executables..."
+
  ../configure --prefix=${_sysroot} --bindir=/usr/bin \
# symlink executables to single directory with no-arch-prefix name
+
    --with-sysroot=${_sysroot} \
mkdir -p ${pkgdir}/usr/bin/cross/${_target}/;
+
    --build=$CHOST --host=$CHOST --target=${_target} \
cd ${pkgdir}/usr/bin/cross/${_target}/;
+
    --with-gcc --with-gnu-as --with-gnu-ld \
for bin in ${pkgdir}/usr/bin/${_target}-*; do
+
    --enable-shared --without-included-gettext \
bbin=`basename "$bin"`;
+
    --disable-nls --disable-debug --disable-win32-registry
ln -s "/usr/bin/${bbin}" `echo "$bbin" | sed "s#^${_target}-##"`;
+
  make || return 1
done
+
  make DESTDIR=${pkgdir}/ install || return 1
 +
 
 +
  # clean-up cross compiler root
 +
  rm -r ${pkgdir}/${_sysroot}/{info,man}
 
}</pre>
 
}</pre>
 
  
 
== Hows and whys ==
 
== Hows and whys ==

Revision as of 18:55, 15 October 2009

Important

This page describes a proposal, not an accepted approach!

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.

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


File Placement

To prevent file conflicts, place everything into /usr/lib/cross-<arch>. 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 namings etc.?

Two reasons:
First, according to File Hierarchy Standard, these files just belong somwhere to /usr. Period.
Second, installing into /opt is a last meassure 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.