[[meta copyright="Copyright © 2007 Free Software Foundation, Inc."]] [[meta license="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled [[GNU_Free_Documentation_License|/fdl]]."]] Feel free to ask questions or report problems on this page's [[discussion]] sub-page. ## Cross Compilation Guide This is a HOWTO to build a cross-compiler on x86 GNU/Linux so you can build GNU Mach, GNU Hurd. This has been successfully built by Vitalie Ciubotaru as posted here [1]. ## cross-gnu [[Thomas_Schwinge|tschwinge]] has written a shell script for building a complete cross-build environment for GNU/Hurd systems. Read through it. Understand it. Then use it. /!\ Be made aware that -- while it is of course possible to build a working cross-compiler -- this is not trivial to do. You'll have to patch several of the source packages. See the corresponding Debian unstable source packages about which Hurd-specific patches exist and check which of them are not yet in the upstream source packages. Not all of the patches from the Debian packages are needed for getting a functional tool chain, though. Applying patches is definitely needed for the glibc, Hurd and GCC source packages, as there are a bunch of outstanding patches that are needed for getting a functional build.
#!/bin/sh

# Cross compile a GNU build environment.

# Written by Thomas Schwinge .

# This script is placed into the public domain; nevertheless, please feel free
# to send any suggestions, improvements, etc. back to me.

# The files are canonically found at
#  and
# .

# Thanks to
# * Thadeu Lima de Souza Cascardo for updating the instructions about getting
#   the source code of GCC using the Subversion repositories.

# Prerequisites:
#
# A build environment for the system you're running the script on is required,
# i.e. a C compiler with the basic libraries and `make'.  You might also need
# `flex' and `bison'.

# Usage:
#
# Place `cross-gnu' and `cross-gnu-env' somewhere in `$PATH', e.g. in `~/bin/'.

# Get the source code of the

# * GNU Binutils, , `src/binutils'
#
#   $ cvs -d:pserver:anoncvs@sources.redhat.com:/cvs/src \
#       co -r binutils-2_17-branch binutils
#   $ mv src binutils-2_17-branch
#
#   Or fetch a tarball from .

# * GNU Compiler Collection, , `src/gcc'
#
#   $ svn co svn://gcc.gnu.org/svn/gcc/branches/BRANCH gcc
#   $ mv gcc BRANCH
#
#   BRANCH is one of `gcc-3_3-branch', `gcc-3_4-branch', `gcc-4_0-branch',
#   `gcc-4_1-branch' or the tag of a released version like `gcc_3_4_3_release'.
#   Or fetch a tarball from .

# * GNU C Library, , `src/glibc'
#
#   $ cvs -d:pserver:anoncvs@sources.redhat.com:/cvs/glibc \
#       co -r glibc-2_3-branch glibc
#   $ mv libc glibc-2_3-branch
#
#   Change `glibc-2_3-branch' to `glibc-2_5-branch' to get the glibc 2.5 branch
#   or omit `-r glibc-2_3-branch' if you want to get the trunk, i.e. the glibc
#   2.6 branch, but note that building both of them currently won't work
#   without heavy patching.
#
#   Or fetch a tarball from .
#
#   If you want to use GCC 4.1 or newer, you'll also need to apply the
#   following patch, for both glibc-2_3-branch and glibc-2_5-branch:
#   .
#
#   If you use a GNU Make version newer than 3.80, you also need to apply the
#   following patch to glibc-2_3-branch:
#   .

# * GNU Hurd, , `src/hurd'
#
#   $ cvs -d:pserver:anoncvs@cvs.gnu.org:/cvsroot/hurd co hurd

# * GNU Mach (gnumach-1-branch), , `src/gnumach'
#
#   $ cvs -d:pserver:anoncvs@cvs.gnu.org:/cvsroot/hurd \
#       co -r gnumach-1-branch gnumach
#   $ mv gnumach gnumach-1-branch

# * GNU Mach Interface Generator, , `src/mig'
#
#   $ cvs -d:pserver:anoncvs@cvs.gnu.org:/cvsroot/hurd co mig

# * GNU Debugger, , `src/gdb'
#
#   This is optional and will only be compiled if present.
#
#   $ cvs -d:pserver:anoncvs@sources.redhat.com:/cvs/src \
#       co -r gdb_6_6-branch gdb
#   $ mv src gdb_6_6-branch
#
#   Or fetch a tarball from .

# Unpack the tarballs if you downloaded any.

# Create a directory where the cross build shall take place and `cd' to that
# directory.  Create a subdirectory `src' and create symbolic links for every
# of the above packages: from `src/PACKAGE' to where you stored or unpacked it.
# If you don't intend to build several cross compilers or use the source trees
# otherwise, you can also directly store the source trees in `src/'.  The
# source trees can be shared between multiple cross build trees since the
# package's build systems are supposed not to modify the files in the source
# trees.  Not all packages adhere to that, but they fail to do so only for
# pre-processed documentation, etc., as far as I can tell.

# Run
# $ ROOT=. cross-gnu
# ... to create the cross build environment in the current directory from the
# sources in `src/'.

# Later, run
# $ ROOT=WHERE_THE_ROOT_OF_THE_CROSS_BUILD_TREE_IS; . cross-gnu-env
# ... to set up `$PATH' (and some other environment variables; have a look at
# cross-gnu-env), so that you can easily use e.g. the cross compiler running
# `$TARGET-gcc'.

# Notes:

# You can re-run `cross-gnu' to rebuild the parts of the sources that have
# changed since the last run.  This might save a lot of time and is especially
# useful if you aren't working with unpacked tarballs, but on CVS's branches or
# want to quickly get a new tool chain with patches you applied to the source
# trees.
# I would, however, _not_ recommend to use this technique when doing major
# changes to the source trees, like switching from gcc-3.3 to gcc-3.4.

# There are several parts marked with `TODO' in this file; feel free to have a
# look at these issues and send the outcome back to me.


# Set up the environment.

. cross-gnu-env

case $? in 0) :;; *) (exit "$?");; esac &&


# Be verbose.

set -x &&


# Create directories.

mkdir -p "$ROOT" &&
cd "$ROOT" &&
mkdir -p bin "$SYS_ROOT"/{include,lib} "$TARGET" &&
ln -sfn "$SYS_ROOT"/{include,lib} "$TARGET"/ &&


# Install the cross GNU Binutils.

mkdir -p "$BINUTILS_SRC".obj &&
cd "$BINUTILS_SRC".obj &&
# We use `config.status''s existence as an indicator whether the package was
# configured already.  (E.g. when running cross-gnu a second time to update the
# tool chain.)
if ./config.status --version > /dev/null 2>&1; then :; else
  "$BINUTILS_SRC"/configure \
    --target="$TARGET" \
    --prefix="$ROOT" \
    --with-sysroot="$SYS_ROOT" \
    --disable-nls
fi &&
"$MAKE" \
  all \
  install &&


# Install a minimal cross GCC to build a cross MIG and the GNU C Library.

mkdir -p "$GCC_SRC".obj &&
cd "$GCC_SRC".obj &&
# Perhaps we already have a complete cross GCC?
if "$TARGET"-gcc --version > /dev/null 2>&1; then :; else
  if ./config.status > /dev/null 2>&1; then :; else
    "$GCC_SRC"/configure \
      --target="$TARGET" \
      --prefix="$ROOT" \
      --with-sysroot="$SYS_ROOT" \
      --disable-nls \
      --disable-shared \
      --without-headers \
      --with-newlib \
      --enable-languages=c
  fi &&

# TODO: GCC 3.3 and GCC 3.4 need this for building libgcc.a.  Not needed for
# GCC 4.0.
  : > "$SYS_ROOT"/include/signal.h &&
  mkdir -p "$SYS_ROOT"/include/sys &&
  : > "$SYS_ROOT"/include/sys/ucontext.h &&

  if "$MAKE" \
      all-gcc \
      install-gcc &&
# TODO: Make glibc happy.  We can not yet build libgcc_eh, but glibc's build
# system wants to link against that library.  A totally empty file is fine for
# binutils-2.16, but not for binutils-2.15.
# .
      echo '/* Empty.  */' > "$SYS_ROOT"/lib/libgcc_eh.a
  then
    # Remove the bogus files if building the cross compiler succeesded.
    rm config.status "$SYS_ROOT"/include/{signal.h,sys/ucontext.h}
  else
    # That indication file might already have been installed, but we do not yet
    # have a complete, working cross compiler.
    rm -f "$ROOT"/bin/"$TARGET"-gcc &&
    exit 100
  fi
fi &&


# Install GNU Mach's header files.

mkdir -p "$GNUMACH_SRC".obj &&
cd "$GNUMACH_SRC".obj &&
if ./config.status --version > /dev/null 2>&1; then :; else
  # `$TARGET-gcc' doesn't work yet (to satisfy the Autoconf checks), but isn't
  # needed either.
  CC=gcc \
  "$GNUMACH_SRC"/configure \
    --host="$TARGET" \
    --prefix=
fi &&
if grep -q install-data "$GNUMACH_SRC"/Makefile.in; then
  "$MAKE" \
    DESTDIR="$SYS_ROOT" \
    install-data
else
  # Old.
  "$MAKE" \
    prefix="$SYS_ROOT" \
    no_deps=t \
    install-headers
fi &&


# Install a cross GNU MIG.

mkdir -p "$MIG_SRC".obj &&
cd "$MIG_SRC".obj &&
if ./config.status > /dev/null 2>&1; then :; else
  "$MIG_SRC"/configure \
    --target="$TARGET" \
    --prefix="$ROOT"
fi &&
"$MAKE" \
  all \
  install &&


# Install the GNU Hurd's header files.

mkdir -p "$HURD_SRC".obj &&
cd "$HURD_SRC".obj &&
if ./config.status --version > /dev/null 2>&1; then :; else
  # `$TARGET-gcc' doesn't work yet (to satisfy the Autoconf checks), but isn't
  # needed either.
  CC=gcc \
  "$HURD_SRC"/configure \
    --host="$TARGET" \
    --prefix= \
    --disable-profile
fi &&
"$MAKE" \
  prefix="$SYS_ROOT" \
  no_deps=t \
  install-headers &&
# Below, we will reconfigure for allowing to build the pthreads library.
if grep -q '^CC = gcc$' config.make
then rm config.status
else :
fi &&


# Install the GNU C Library.

# Do we already have the GNU C library installed?
if test -h "$SYS_ROOT"/lib/ld.so; then :; else
  mkdir -p "$GLIBC_SRC".obj &&
  cd "$GLIBC_SRC".obj &&
  if ./config.status > /dev/null 2>&1; then :; else
    # `--build' has to be set to make sure that glibc is cross compiled.
    # TODO: Unless overridden, the build system is forced to think that the
    # linker doesn't support the `-z relro' flag, because there are unfixed
    # bugs in glibc w.r.t. that flag.  Likewise for `--without-tls'.
    "$GLIBC_SRC"/configure \
      --without-cvs \
      --build="`"$GLIBC_SRC"/scripts/config.guess`" \
      --host="$TARGET" \
      --prefix= \
      --with-headers="$SYS_ROOT"/include \
      --disable-profile \
      ${CROSS_GNU_TLS---without-tls} \
      ${CROSS_GNU_Z_RELRO-libc_cv_z_relro=no}
  fi &&
  if "$MAKE" \
       install_root="$SYS_ROOT" \
       all \
       install
  then
    # TODO: Why doesn't `make install' do that?
    ln -sf ld.so.1 "$SYS_ROOT"/lib/ld.so &&
    if [ "$CROSS_GNU_REINSTALL_GLIBC" = n ]; then :; else
      # Force re-linking files once libgcc_eh is available.  TODO: Is the
      # following enough?
      rm -f "$GLIBC_SRC".obj/config.status
#      rm -rf "$GLIBC_SRC".obj
    fi
  else
    # That indication file might already have been installed, but we do not yet
    # have a complete, working installation of the GNU C library.
    rm -f "$SYS_ROOT"/lib/ld.so
    exit 100
  fi
fi &&


# Install the GNU Hurd's pthreads library.

cd "$HURD_SRC".obj &&
if ./config.status --version > /dev/null 2>&1; then :; else
  "$HURD_SRC"/configure \
    --host="$TARGET" \
    --prefix= \
    --disable-profile
fi &&
"$MAKE" \
  libpthread &&
"$MAKE" \
  prefix="$SYS_ROOT" \
  libihash-install libpthread-install &&


# Install a complete cross GCC.

cd "$GCC_SRC".obj &&
if ./config.status > /dev/null 2>&1; then :; else
  # TODO: At the moment we only configure for creating a C compiler.
  "$GCC_SRC"/configure \
    --target="$TARGET" \
    --prefix="$ROOT" \
    --with-sysroot="$SYS_ROOT" \
    --disable-nls \
    --enable-languages=c
fi &&
# Remove the bogus libgcc_eh.
rm -f "$SYS_ROOT"/lib/libgcc_eh.a &&
"$MAKE" \
  all \
  install &&


# Install the GNU C Library.

mkdir -p "$GLIBC_SRC".obj &&
cd "$GLIBC_SRC".obj &&
if ./config.status > /dev/null 2>&1; then :; else
  # `--build' has to be set to make sure that glibc is cross compiled.
  # TODO: Unless overridden, the build system is forced to think that the
  # linker doesn't support the `-z relro' flag, because there are unfixed
  # bugs in glibc w.r.t. that flag.  Likewise for `--without-tls'.
  "$GLIBC_SRC"/configure \
    --without-cvs \
    --build="`"$GLIBC_SRC"/scripts/config.guess`" \
    --host="$TARGET" \
    --prefix= \
    --with-headers="$SYS_ROOT"/include \
    --disable-profile \
    ${CROSS_GNU_TLS---without-tls} \
    ${CROSS_GNU_Z_RELRO-libc_cv_z_relro=no}
fi &&
"$MAKE" \
  install_root="$SYS_ROOT" \
  all \
  install &&


# Install a cross GDB, if requested.

if test -d "$GDB_SRC"/; then
  mkdir -p "$GDB_SRC".obj &&
  cd "$GDB_SRC".obj &&
  if ./config.status > /dev/null 2>&1; then :; else
    "$GDB_SRC"/configure \
      --target="$TARGET" \
      --prefix="$ROOT" \
      --with-sysroot="$SYS_ROOT" \
      --disable-nls
  fi &&
  "$MAKE" \
    all \
    install &&


  # If possible, install a cross compiled `gdbserver' to be ran on the TARGET
  # system.

  if grep -q '86-\*-gnu\*' "$GDB_SRC"/gdb/gdbserver/README; then
    mkdir -p gdb/gdbserver &&
    cd gdb/gdbserver &&
    if ./config.status > /dev/null 2>&1; then :; else
      "$GDB_SRC"/gdb/gdbserver/configure \
        --host="$TARGET" \
        --prefix="$SYS_ROOT"
    fi &&
    "$MAKE" \
      all \
      install
  else :
  fi
fi &&


# Success.

echo "$0"': Everything should be in place now.'
## cross-gnu-env
#!/bin/sh

# Cross compile a GNU build environment.

# Written by Thomas Schwinge .

# This script is placed into the public domain; nevertheless, please feel free
# to send any suggestions, improvements, etc. back to me.

# The files are canonically found at
#  and
# .


# Functions from Paul Jarc's prjlibs available at
# .

# sh/set.sh
case $? in 0) :;; *) (exit "$?");; esac &&
prj_set() {
  eval "$1=\${2?}"
}

# sh/set_default.sh
case $? in 0) :;; *) (exit "$?");; esac &&
prj_set_default() {
  : "${2?}" &&
  eval "
  if test \"\${$1+x}\" = x; then :; else
    $1=\$2
  fi"
}

# sh/unset.sh
case $? in 0) :;; *) (exit "$?");; esac &&
prj_unset() {
  while test "$#" != 0; do
    { eval "$1=" &&
      unset "$1" &&
      shift
    } || return "$?"
  done
}

# sh/x2.sh
case $? in 0) :;; *) (exit "$?");; esac &&
prj_x2() {
  : "${2?}" &&
  "$@" &&
  export "$2"
}

case $? in 0) :;; *) (exit "$?");; esac &&


# Create a clean environment.

prj_x2 prj_set LC_ALL C &&
prj_unset ASFLAGS CFLAGS CPPFLAGS CXXFLAGS LDFLAGS &&
prj_unset MAKEFLAGS &&


# Environment variables.

# `$ROOT' defaults to `~/tmp/gnu'.
prj_x2 prj_set_default ROOT ~/tmp/gnu &&
# `$ROOT' must specify an absolute path.
case $ROOT in
  /*)
    :;;
  *)
    ROOT=`cd "$ROOT" && pwd`;;
esac &&

prj_x2 prj_set_default SYS_ROOT "$ROOT"/sys_root &&

prj_x2 prj_set_default TARGET i586-pc-gnu &&

prj_x2 prj_set_default BINUTILS_SRC "$ROOT"/src/binutils &&
prj_x2 prj_set_default GCC_SRC "$ROOT"/src/gcc &&
prj_x2 prj_set_default GDB_SRC "$ROOT"/src/gdb &&
prj_x2 prj_set_default GLIBC_SRC "$ROOT"/src/glibc &&
prj_x2 prj_set_default GNUMACH_SRC "$ROOT"/src/gnumach &&
prj_x2 prj_set_default HURD_SRC "$ROOT"/src/hurd &&
prj_x2 prj_set_default MIG_SRC "$ROOT"/src/mig &&

# TODO.  See cross-gnu.
prj_x2 prj_set_default CROSS_GNU_REINSTALL_GLIBC y &&

prj_x2 prj_set PATH "$ROOT"/bin:"$PATH" &&

if gmake --version 2> /dev/null | grep -q GNU
then prj_x2 prj_set MAKE gmake
else prj_x2 prj_set MAKE make
fi
-- ShakthiKannan - 03 Oct 2007 ## References * *