This post is a little rough, and is intended both as a memory aid for myself and as an example for anyone else who needs to know this stuff. I’ve recently decided to push toward x86_64 support in my toy/research OS project, and needed to build a GCC cross compiler for that target. In my case I already had an x86 cross compiler built, but I’ve tried to make the steps general for those that don’t.
These steps are tested with binutils 2.26.1 and GCC 6.1.0. I’m using those versions as they match the version of my x86 cross compiler – These steps might work with the more recent versions, but I can’t guarantee it. I will at some point update my cross compilers, at which point I’ll update these steps.
1. Go to your $HOME/src. Create first if needed.
# mkdir ~/src
# cd ~/src
2. Set up prefixes. PATH is only needed if not already set (e.g. this is your first cross compiler on this system).
# export PREFIX="$HOME/opt/cross"
# export TARGET=x86_64-elf
# export PATH="$PREFIX/bin:$PATH"
3. Configure, build and install binutils
# tar xf /path/to/downloaded/binutils-2.26.1.tar.gz
# mkdir build-binutils-x86_64
# cd build-binutils-x86_64
# ../binutils-2.26.1/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror
# make && make install
4. Extract GCC
# cd ..
# tar xf /path/to/downloaded/gcc-6.1.0.tar.gz
Ensure libgcc is built with no redzone – Add this:
MULTILIB_OPTIONS += mno-red-zone
MULTILIB_DIRNAMES += no-red-zoneto the following (new) file:
gcc-6.1.0/gcc/config/i386/t-x86_64-elf
And then make sure GCC configure knows about the new config:
# vim gcc-6.1.0/gcc/config.gcc
/x86_64-\*-elf\*)And insert:
tmake_file="${tmake_file} i386/t-x86_64-elf"
above the tm_file line.
5. Configure GCC
# mkdir build-gcc-x86_64
# cd build-gcc-x86_64
# ../gcc-x.y.z/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
6. Build GCC
# make all-gcc
Go make coffee/eat out at a restaurant/vacation in Barbados…
Note: If building with newer GCC (Found with 7.3.1), there’s an issue in the 6.1.0 source. If you see error:
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
relating to
gcc/ubsan.c
, then you’ll need to edit that file, and change line 1473 from:
|| xloc.file == '\0' || xloc.file[0] == '\xff'
to:
|| xloc.file[0] == '\0' || xloc.file[0] == '\xff'
7. Build libgcc
# make all-target-libgcc
8. Install GCC and libgcc
# make install-gcc
# make install-target-libgcc
9. Check the no-redzone libgcc is being used properly when -mno-red-zone is passed:
# x86_64-elf-gcc -mno-red-zone -print-libgcc-file-name
Should print (note the no-red-zone in the path):
$HOME/opt/cross/lib/gcc/x86_64-elf/6.1.0/no-red-zone/libgcc.a