Cross-compiling tools package guidelines

From ArchWiki
Revision as of 09:44, 13 October 2009 by Hotspur (talk | contribs) (Hows and whys)
Jump to: navigation, search


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

Place all the files in the /usr/, to avoid conflicts with existing binaries, prefix them with architecture name (typically, the best way is to use the target name specified during the build).


This is PKGBUILD for GCC for MIPS. Things worth noticing are:

  • manually specifying where to find the as and ld binaries
  • usage of ${_pkgname} and ${_target} variables to make the code more readable
  • removal of the duplicated/conflicting files
# Contributor: Your name <>
pkgdesc="The GNU Compiler Collection for the MIPS architecture"
arch=('i686' 'x86_64')
depends=('mpfr' 'sh' 'cross-mips-binutils')
options=('!ccache' '!distcc' '!emptydirs' '!libtool' '!strip')

build() {
	cd ${srcdir}/${_pkgname}-${pkgver}
	./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..."
	# symlink executables to single directory with no-arch-prefix name
	mkdir -p ${pkgdir}/usr/bin/cross/${_target}/;
	cd ${pkgdir}/usr/bin/cross/${_target}/;
	for bin in ${pkgdir}/usr/bin/${_target}-*; do
		bbin=`basename "$bin"`;
		ln -s "/usr/bin/${bbin}" `echo "$bbin" | sed "s#^${_target}-##"`;

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 to /usr. Period.
Second, installing into /opt is a last meassure when there is no other option.

Binutils creates some ugly looking directories (architecture named) directly under /usr!

You need to manually specify tooldir during make (both with make all and make install).
make tooldir=/usr all || return 1
make tooldir=/usr DESTDIR=${pkgdir} install || return 1

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.