Building a cross-compiler

Michael Witten mfwitten@MIT.EDU
Tue Jan 29 05:05:00 GMT 2008

On 28 Jan 2008, at 6:44 PM, Wenton L. Davis wrote:

> John Carter wrote:
>> It's a _very_ dark art....
> No kidding!!!!

I disagree wholeheartedly.

Creating a cross compiler _should_ be the easiest
thing in the world, but the gcc is so backasswards
that it can be troublesome.

>> Some hints:...
>> There is a nasty tangly dependency between binutils, libc and the
>> compiler.
>> Last time I did it, I found I had to have the binutils --prefix  
>> directory
>> the same --prefix as the compiler.

This is definitely the case; gcc is really just an
interface to a bunch of different tools, so it needs
to know where to find those tools.

It would be nice if there were a configure directive
to specify the location of binutils tools for greater
flexibility. For now, just make --prefix the same for

In any case, you're supposed to be able to put the
binutils source subdirectories (gprof, opcodes,
bintutils, ...) inside the top level of the gcc source
code so that one configure invocation handles both; both
source trees are actually 2 separate views of a larger

> At this point, I tried the brute force, copying the exact command  
> line, but adding to it the -I../../(etc) to find the unistd.h and  
> pthreads.h, but it failed because of an #endif without #if error...  
> I thought I'd manually modify this file, but it was automagically  
> created by fixincludes.  (?!?!?)

Do you need libc on these other targets? If not, use
--without-headers to indicate that you have no intention
of building libc or the runtime libraries like libstdc++.
See below.

If --without-headers is indeed what you want, then make
sure you specify the --target properly. If you include
'linux' in there, the build will fail trying to use glibc
headers to build parts of libgcc that are Linux specific
(or something like that), because--as stated before--the
gcc is backasswards.

If you need libc, I've seen people do 2 things, you should
probably grab the libraries and headers from each target
and put them (or build them on each target and install them)
into a directory on your host machine; pass this directory
to --with-sysroot during the configuration of gcc.

That's my understanding.

>> You then need to have the target libc in the appropriate level of the
>> gcc src tree. Your error messages suggest to me you either don't have
>> a libc build, or have it at the wrong level.

I'm not sure this is correct. Take a look at

I have always only made "naked" (libc-less) cross
compilers, but I believe that configuration switch
should be hardcoded into the final gcc to tell it
where to look for libc stuff (much in the same way
I'd like to be able to configure gcc to look for binutils
in some nonstandard place).

> OK, this could very easily be the problem.  I was assuming this was  
> built as a part of the gcc build, but that does not appear to be the  
> case.  But if the compiler needs libc to build, and libc is built by  
> compiling.... which came first, the chicken or the egg?
>> I found I couldn't build it "out the box" for the variants I was
>> building for, I had to find and apply some patches. (Not too
>> surprising, given the combinatorial explosion of host os X host CPU X
>> target os X target CPU X libc implementation X libc version X  
>> binutils
>> version, they simply can't test everything.)
> I absolutely agree... there must be several thousand combinations.   
> I sometimes wonder if this works against the linux community rather  
> than for it?

Against. Then again, Linux can't be built easily outside of
standard Linuxy environments, as it too is backasswards, because
it depends on other backasswards GNU setups. For instance, the
kernel requires certain headers, like /etc/include/elf.h, but elf.h
is only included with glibc. Then one must ask, why the hell would
glibc concern itself with elf.h ? That should be part of binutils
or something.

>> Good Luck! I can email you my scripts for building things, can't
>> guarantee they'll work for you though! Being in Ruby, I find them  
>> easy to
>> read / maintain than the cross gcc shell script project.

I have a Gentoo Linux box that is rather slow. I have a much faster
PowerBook G4. Therefore, I wanted to use the PowerBook to compile
stuff for use with the Gentoo box.

Interestingly, distcc (which distributes compilation across machines)
preprocesses code on the one client machine, so that only direct comp-
ilation to Object Code is necessary on each server. This means the  
need not have libraries or headers common to the client machine.

For this reason, I built a naked cross compiler on the PowerBook:
(or something similar)

	tar xjf binutils-2.17.tar.bz2
	mv binutils-2.17 src
	mkdir build
	cd build
	export PREFIX=/usr/local/xgcc
	export TARGET=i686-elf
	../src/configure --target=$TARGET --prefix=$PREFIX --disable-nls
	make -j3
	sudo make install
	tar xjf gcc-core-4.1.2.tar.bz2 && tar xjf gcc-g++-4.1.2.tar.bz2
	mv gcc-4.1.2 src
	mkdir build
	cd build
	export PATH=$PATH:$PREFIX/bin
	../src/configure --target=$TARGET --prefix=$PREFIX --disable-nls -- 
enable-languages=c,c++ --without-headers
	MACOSX_DEPLOYMENT_TARGET=10.4 make -j3 all-gcc
	sudo make install-gcc


I had to link $PREFIX/bin/i686-elf-* to $PREFIX/bin/i686-pc-linux-gnu- 
*, because of
backasswardsness; there is a gcc configuration switch to mangle the  
names, but
this can cause problems if you configure binutils with mangled names  

I hope this helps / is correct.

Michael Witten

More information about the Gcc-help mailing list