compiling a 32/64bit biarch toolchain

Anton Blanchard anton at samba.org
Wed Jan 14 17:32:50 EST 2004


Hi,

I recently had to compile a 32/64bit biarch toolchain and there were a
number of tricks required. Heres a quick attempt to document them.

Better run the instructions below by hand, theres a good chance you'll
blow up somewhere in the middle and have to fix things by hand.
Hopefully someone will come up with a nicer way to do this :)

I have also attached two patches:

ngpt_patch - ngpt is doing naughty things in autoconf, its trying to
link stuff before we have a libc available. Fix that by removing the
tests, they are just some sanity checks and our toolchain passes.
(I needed this patch to compile glibc)

glibc64_backward_compatibility_patch - produces an old school glibc,
only required if you have existing applications.

Anton


#!/bin/sh

# grab CVS binutils
# grab CVS gcc (3.3 or 3.4)
# grab Alan Modra's latest gcc patch (ftp://ftp.linuxppc64.org/pub/people/amodra/)
# grab CVS glibc

rm -rf src-ppc64 gcc-ppc64 glibc-ppc32 glibc-ppc64
mkdir src-ppc64 gcc-ppc64 glibc-ppc32 glibc-ppc64

cd src-ppc64
../build_binutils
cd ..

cd gcc-ppc64
../build_gcc_1
cd ..

#
# Stop here if you are only building a toolchain to compile kernels
#

cd glibc-ppc32
../build32_glibc_1
rm -rf ../glibc-ppc32/*
../build32_glibc_2
cd ..

cd glibc-ppc64
../build_glibc_1
rm -rf ../glibc-ppc64/*
../build_glibc_2
cd ..

rm -rf gcc-ppc64/*
cd gcc-ppc64
../build_gcc_2
cd ..

rm -rf glibc-ppc32/*
cd glibc-ppc32
../build32_glibc_3
cd ..

rm -rf glibc-ppc64/*
cd glibc-ppc64
../build_glibc_3
cd ..

# Dont seem to need this in recent 3.3/3.4 builds:
#
# cd /usr/local/lib/gcc-lib/powerpc-linux/${GCC_VERSION}/include
# rm -rf root asm linux bits
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/src
HOST=powerpc-linux
MAKEOPTS=-j20

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT PATH

$SRC/configure --prefix=$ROOT \
 --build=$HOST --host=$HOST --disable-nls --target=powerpc-linux \
 --enable-targets=powerpc64-linux

make $MAKEOPTS
make install

cd $ROOT/bin
for z in addr2line ar as c++filt ld nm objcopy objdump ranlib readelf \
         size strings strip; do
# The next line should only do something on a powerpc-linux host
  test -x powerpc-linux-$z || ln -sf $z powerpc-linux-$z
  ln -sf powerpc-linux-$z powerpc64-linux-$z
done
rm powerpc64-linux-as powerpc64-linux-ld
cat > powerpc64-linux-as << \EOF
#! /bin/sh
exec /usr/local/ppc64/bin/powerpc-linux-as -a64 "$@"
EOF
cat > powerpc64-linux-ld << \EOF
#! /bin/sh
exec /usr/local/ppc64/bin/powerpc-linux-ld -melf64ppc "$@"
EOF
chmod a+x powerpc64-linux-as powerpc64-linux-ld
mkdir -p $ROOT/powerpc64-linux/bin
cd $ROOT/powerpc64-linux/bin
for z in ar nm ranlib strip; do
  test -x $z || ln -sf ../../powerpc-linux/bin/$z $z
done
ln -sf $ROOT/bin/powerpc64-linux-as as
ln -sf $ROOT/bin/powerpc64-linux-ld ld
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/gcc-3.3
HOST=powerpc-linux
MAKEOPTS=-j20

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT PATH

$SRC/configure --prefix=$ROOT \
 --build=$HOST --host=$HOST --target=powerpc-linux --enable-biarch \
 --disable-nls --disable-threads --disable-shared --enable-languages=c

make $MAKEOPTS
make install

# work out the gcc version
GCC_VERSION="`grep "^gcc_version " Makefile | sed 's/gcc_version[ 	=]*//'`"

# Make a link so configure knows we have a 64 bit compiler too.
cd $ROOT/bin
for z in gcc cpp; do
# The following line should only do something on a powerpc-linux host.
  test -x powerpc-linux-$z || ln -sf $z powerpc-linux-$z
  cat > powerpc64-linux-$z << EOF
#! /bin/sh
exec /usr/local/ppc64/bin/powerpc-linux-$z -m64 "\$@"
EOF
  chmod a+x powerpc64-linux-$z
done
cd $ROOT/powerpc64-linux/bin
ln -sf $ROOT/bin/powerpc64-linux-gcc gcc

# Allow the biarch compiler to find the ppc64 library and crt files.
cd $ROOT/powerpc-linux
ln -sf ../powerpc64-linux/lib lib64

# The following is a hack for a glibc.  As at 2003-08-11, glibc requires
# libgcc_eh.a, but this is only built with a shared libgcc.
cd $ROOT/lib/gcc-lib/powerpc-linux/$GCC_VERSION
ln -sf libgcc.a libgcc_eh.a
ln -sf libgcc.a 64/libgcc_eh.a
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/libc_work
HOST=powerpc-linux
MAKEOPTS=-j20
HEADERS=/scratch/anton/ameslab-2.5/include

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT HEADERS PATH

( cd $HEADERS && rm asm )
( cd $HEADERS && ln -sf asm-ppc asm )

$SRC/configure \
 --prefix=$ROOT/powerpc-linux --build=$HOST --host=powerpc-linux \
 --with-headers=$HEADERS --without-cvs --with-tls \
 --enable-add-ons=nptl --disable-shared

make $MAKEOPTS
make install
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/libc_work
HOST=powerpc-linux
MAKEOPTS=-j20
HEADERS=/scratch/anton/ameslab-2.5/include

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT HEADERS PATH

( cd $HEADERS && rm asm )
( cd $HEADERS && ln -sf asm-ppc asm )

$SRC/configure \
 --prefix=$ROOT/powerpc-linux --build=$HOST --host=powerpc-linux \
 --with-headers=$HEADERS --without-cvs --with-tls \
 --enable-add-ons=nptl --enable-shared

make $MAKEOPTS
make install

mkdir -p $ROOT/powerpc-linux/include/linux/
mkdir -p $ROOT/powerpc-linux/include/asm/
mkdir -p $ROOT/powerpc-linux/include/asm-generic/
cp -a $HEADERS/linux/* $ROOT/powerpc-linux/include/linux/
cp -a $HEADERS/asm-ppc/* $ROOT/powerpc-linux/include/asm/
cp -a $HEADERS/asm-generic/* $ROOT/powerpc-linux/include/asm-generic/
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/libc_work
HOST=powerpc-linux
MAKEOPTS=-j20
HEADERS=/scratch/anton/ameslab-2.5/include

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT HEADERS PATH

( cd $HEADERS && rm asm )
( cd $HEADERS && ln -sf asm-ppc64 asm )

$SRC/configure \
 --prefix=$ROOT/powerpc64-linux --build=$HOST --host=powerpc64-linux \
 --with-headers=$HEADERS --without-cvs --with-tls \
 --enable-add-ons=nptl --disable-shared

make $MAKEOPTS
make install
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/libc_work
HOST=powerpc-linux
MAKEOPTS=-j20
HEADERS=/scratch/anton/ameslab-2.5/include

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT HEADERS PATH

( cd $HEADERS && rm asm )
( cd $HEADERS && ln -sf asm-ppc64 asm )

$SRC/configure \
 --prefix=$ROOT/powerpc64-linux --build=$HOST --host=powerpc64-linux \
 --with-headers=$HEADERS --without-cvs --with-tls \
 --enable-add-ons=nptl --enable-shared

make $MAKEOPTS
make install

mkdir -p $ROOT/powerpc64-linux/include/linux/
mkdir -p $ROOT/powerpc64-linux/include/asm/
mkdir -p $ROOT/powerpc64-linux/include/asm-generic/
cp -a $HEADERS/linux/* $ROOT/powerpc64-linux/include/linux/
cp -a $HEADERS/asm-ppc64/* $ROOT/powerpc64-linux/include/asm/
cp -a $HEADERS/asm-generic/* $ROOT/powerpc64-linux/include/asm-generic/
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/gcc-3.4
HOST=powerpc-linux
MAKEOPTS=-j20

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT PATH

# Fix for some biarch madness
mkdir $ROOT/powerpc-linux/lib/64/nof
for i in crt?.o
do
	ln -s $ROOT/powerpc-linux/lib/64/nof/$i ../../../lib64/
done

$SRC/configure --prefix=$ROOT \
 --build=$HOST --host=$HOST --target=powerpc-linux --enable-biarch \
 --disable-nls --enable-shared --enable-__cxa_atexit \
 --enable-languages=c,c++

 #--enable-languages=c,c++,f77 - add f77 if you want
 #--with-headers=$ROOT/powerpc-linux/include - not needed any more?

make $MAKEOPTS
make install

# work out the gcc version
GCC_VERSION="`grep "^gcc_version " Makefile | sed 's/gcc_version[ 	=]*//'`"

cd $ROOT/bin
for z in gcc cpp g++ c++; do
# The following line should only do something on a powerpc-linux host.
  test -x powerpc-linux-$z || ln -sf $z powerpc-linux-$z
  cat > powerpc64-linux-$z << EOF
#! /bin/sh
exec $ROOT/bin/powerpc-linux-$z -m64 -isystem /usr/local/ppc64/lib/gcc-lib/powerpc-linux/${GCC_VERSION}/include -isystem /usr/local/ppc64/powerpc64-linux/include "\$@"
EOF
  chmod a+x powerpc64-linux-$z
done
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/libc_work
HOST=powerpc-linux
MAKEOPTS=-j20
HEADERS=/scratch/anton/ameslab-2.5/include

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT HEADERS PATH

( cd $HEADERS && rm asm )
( cd $HEADERS && ln -sf asm-ppc asm )

$SRC/configure \
 --prefix=$ROOT/powerpc-linux --build=$HOST --host=powerpc-linux \
 --with-headers=$HEADERS --without-cvs --with-tls \
 --enable-add-ons=nptl --enable-shared

make $MAKEOPTS
make install
-------------- next part --------------
#!/bin/sh -e

ROOT=/usr/local/ppc64
SRC=/scratch/anton/toolchain/new/libc_work
HOST=powerpc-linux
MAKEOPTS=-j20
HEADERS=/scratch/anton/ameslab-2.5/include

PATH=$ROOT/bin:/usr/bin:/bin
export ROOT HEADERS PATH

( cd $HEADERS && rm asm )
( cd $HEADERS && ln -sf asm-ppc64 asm )

$SRC/configure \
 --prefix=$ROOT/powerpc64-linux --build=$HOST --host=powerpc64-linux \
 --with-headers=$HEADERS --without-cvs --with-tls \
 --enable-add-ons=nptl --enable-shared

make $MAKEOPTS
make install
-------------- next part --------------
Index: nptl/sysdeps/pthread/configure
===================================================================
RCS file: /cvs/glibc/libc/nptl/sysdeps/pthread/configure,v
retrieving revision 1.10
diff -u -r1.10 configure
--- nptl/sysdeps/pthread/configure	3 Dec 2003 06:50:01 -0000	1.10
+++ nptl/sysdeps/pthread/configure	14 Jan 2004 05:29:40 -0000
@@ -24,136 +24,3 @@
 fi


-echo "$as_me:$LINENO: checking for forced unwind support" >&5
-echo $ECHO_N "checking for forced unwind support... $ECHO_C" >&6
-if test "${libc_cv_forced_unwind+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <unwind.h>
-int
-main ()
-{
-
-struct _Unwind_Exception exc;
-struct _Unwind_Context *context;
-_Unwind_GetCFA (context)
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  libc_cv_forced_unwind=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-libc_cv_forced_unwind=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $libc_cv_forced_unwind" >&5
-echo "${ECHO_T}$libc_cv_forced_unwind" >&6
-if test $libc_cv_forced_unwind = yes; then
-  cat >>confdefs.h <<\_ACEOF
-#define HAVE_FORCED_UNWIND 1
-_ACEOF
-
-  old_CFLAGS="$CFLAGS"
-  CFLAGS="$CFLAGS -Werror -fexceptions"
-  echo "$as_me:$LINENO: checking for C cleanup handling" >&5
-echo $ECHO_N "checking for C cleanup handling... $ECHO_C" >&6
-if test "${libc_cv_c_cleanup+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-    cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-#include <stdio.h>
-void cl (void *a) { }
-int
-main ()
-{
-
-  int a __attribute__ ((cleanup (cl)));
-  puts ("test")
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest$ac_exeext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  libc_cv_c_cleanup=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-libc_cv_c_cleanup=no
-fi
-rm -f conftest.err conftest.$ac_objext \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $libc_cv_c_cleanup" >&5
-echo "${ECHO_T}$libc_cv_c_cleanup" >&6
-  CFLAGS="$old_CFLAGS"
-  if test $libc_cv_c_cleanup = no; then
-    { { echo "$as_me:$LINENO: error: the compiler must support C cleanup handling" >&5
-echo "$as_me: error: the compiler must support C cleanup handling" >&2;}
-   { (exit 1); exit 1; }; }
-  fi
-else
-  { { echo "$as_me:$LINENO: error: forced unwind support is required" >&5
-echo "$as_me: error: forced unwind support is required" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-------------- next part --------------
Index: shlib-versions
===================================================================
RCS file: /cvs/glibc/libc/shlib-versions,v
retrieving revision 1.66
diff -u -r1.66 shlib-versions
--- shlib-versions	5 Sep 2002 09:32:03 -0000	1.66
+++ shlib-versions	14 Jan 2004 05:29:37 -0000
@@ -24,7 +24,7 @@
 s390x-.*-linux.*        DEFAULT			GLIBC_2.2
 cris-.*-linux.*		DEFAULT			GLIBC_2.2
 x86_64-.*-linux.*       DEFAULT			GLIBC_2.2.5
-powerpc64-.*-linux.*	DEFAULT			GLIBC_2.3
+powerpc64-.*-linux.*	DEFAULT			GLIBC_2.2.5
 .*-.*-gnu-gnu.*		DEFAULT			GLIBC_2.2.6

 # Configuration		Library=version		Earliest symbol set (optional)
@@ -70,7 +70,7 @@
 mips.*-.*-linux.*	ld=ld.so.1		GLIBC_2.0 GLIBC_2.2
 hppa.*-.*-.*		ld=ld.so.1		GLIBC_2.2
 s390x-.*-linux.*	ld=ld64.so.1		GLIBC_2.2
-powerpc64.*-.*-linux.*	ld=ld64.so.1		GLIBC_2.3
+powerpc64.*-.*-linux.*	ld=ld64.so.1		GLIBC_2.2.5
 cris-.*-linux.*		ld=ld.so.1		GLIBC_2.2
 x86_64-.*-linux.*	ld=ld-linux-x86-64.so.2	GLIBC_2.2.5
 # We use the ELF ABI standard name for the default.
Index: linuxthreads/shlib-versions
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/shlib-versions,v
retrieving revision 1.10
diff -u -r1.10 shlib-versions
--- linuxthreads/shlib-versions	5 Sep 2002 10:14:32 -0000	1.10
+++ linuxthreads/shlib-versions	14 Jan 2004 05:29:38 -0000
@@ -7,5 +7,5 @@
 s390x-.*-linux.*	libpthread=0		GLIBC_2.2
 cris-.*-linux.*		libpthread=0		GLIBC_2.2
 x86_64-.*-linux.*	libpthread=0		GLIBC_2.2.5
-powerpc64-.*-linux.*	libpthread=0		GLIBC_2.3
+powerpc64-.*-linux.*	libpthread=0		GLIBC_2.2.5
 .*-.*-linux.*		libpthread=0
Index: sysdeps/unix/sysv/linux/powerpc/bits/stat.h
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/powerpc/bits/stat.h,v
retrieving revision 1.7
diff -u -r1.7 stat.h
--- sysdeps/unix/sysv/linux/powerpc/bits/stat.h	26 Jun 2003 17:00:37 -0000	1.7
+++ sysdeps/unix/sysv/linux/powerpc/bits/stat.h	14 Jan 2004 05:29:43 -0000
@@ -24,13 +24,18 @@
 #include <bits/wordsize.h>

 /* Versions of the `struct stat' data structure.  */
-#define _STAT_VER_LINUX_OLD	1
-#define _STAT_VER_KERNEL	1
-#define _STAT_VER_SVR4		2
-#define _STAT_VER_LINUX	  3
 #if __WORDSIZE == 32
+# define _STAT_VER_LINUX_OLD	1
+# define _STAT_VER_KERNEL	1
+# define _STAT_VER_SVR4		2
+# define _STAT_VER_LINUX	  3
 # define _STAT_VER		_STAT_VER_LINUX
 #else
+/* We used STAT_VER_LINUX 3 in glibc 2.2.5, which has the exact
+ * layout as the kernel struct stat, so we define them to be the same.
+ */
+# define _STAT_VER_LINUX	3
+# define _STAT_VER_KERNEL	3
 # define _STAT_VER		_STAT_VER_KERNEL
 #endif



More information about the Linuxppc64-dev mailing list