linker error

Alan Modra amodra@bigpond.net.au
Wed Oct 29 22:41:00 GMT 2008


On Wed, Oct 29, 2008 at 05:59:51PM +0100, Dominik Táborský wrote:
> I'm trying to build bash for i586, so I have built glibc for i586
> already and am trying to link bash with these libraries, in /lib/i586.

It is quite difficult to use two or more different versions of glibc
on a system.  There are two problems to solve:
a) At compile time, ensure you use the new include files when
   compiling apps that should use the new libc.  Also make sure that
   you link against the new ld.so and libc.so.
b) At run time, use the correct ld.so and libc.so.  The basic problem
   is that ld.so and libc.so share data structures.  So if at run time
   you happen to use the old ld.so with the new libc.so, or vice
   versa, you are likely to get segfaults.  Your existing system
   binaries and libraries may or may not work with the new
   ld.so/libc.so.  If they don't you have a new level of pain.

Attached is a script I developed some time ago to solve this for
powerpc.  It may need updating..

-- 
Alan Modra
Australia Development Lab, IBM
-------------- next part --------------
#! /bin/bash
# Build a native toolchain, binutils+gcc+glibc+gdb, that coexists rather
# than replacing the system tools and libraries.  They will be built in
# build/* relative to the current working dir.

# Where the toolchain should be installed
dest=/home/alan/toolchain

# Where to install binutils and gcc that use the host glibc
# If this isn't set it is assumed that the host tools are sufficiently recent
# to support -msecure-plt.
host_dest=/home/alan/gnu

# Where various sources may be found.  These are all copied to src/*
# relative to the current working dir.
# If using gcc earlier than 4.3, the patches in
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17621 comment #16 must
# be applied.
kernel_src=/src/ppc-2.6.25
gcc_src=/src/gcc-current
gmp_src=/src/gmp-4.2.2
mpfr_src=/src/mpfr-2.3.1
libz_src=/src/zlib-1.2.3
glibc_src=/src/libc-current
binutils_src=/src/binutils-current
ncurses_src=/src/ncurses-5.6
gdb_src=/src/gdb-current

# If this is set, then binutils and gdb will be extracted from the cygnus
# source tree.
cygnus_src=/src/cygnus

# If combined_tree is set to "yes", then a combined binutils/gcc tree will be
# built.  In general this only works for mainline CVS source, because the top
# level directory make and configure files of each need to be virtually
# identical.
conbined_tree=

# Stop on errors.
set -e


# Find as and ld for gcc
if test -n "${host_dest}"; then
  # We'll be building new ones.
  gcc_as="${host_dest}"/bin/as
  gcc_ld="${host_dest}"/bin/ld
else
  # Find as and ld from the users path
  save_IFS="$IFS"
  IFS=:
  for d in $PATH; do
    if test -x "$d/as"; then
      gcc_as="$d/as"
      break
    fi
  done
  for d in $PATH; do
    if test -x "$d/ld"; then
      gcc_ld="$d/ld"
      break
    fi
  done
  IFS="$save_IFS"
  if test -z "$gcc_as"; then
    echo "Cannot find as!"
    exit 1
  fi
  if test -z "$gcc_ld"; then
    echo "Cannot find ld!"
    exit 1
  fi
  # Sanity check the ld we found
  if ! "$gcc_ld" --help 2>&1 | grep -q bss-plt; then
    echo "$gcc_ld is too old!"
    exit 1
  fi
  # Also check host gcc
  if ! gcc -v --help 2>&1 | grep -q secure-plt; then
    echo "host gcc is too old!"
    exit 1
  fi
fi


# Set up local copies of sources.

if test -n "${kernel_src}"; then
  mkdir -p src/kernel
  rsync -rptgo --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    "${kernel_src}"/ src/kernel/
  kernel_src=`cd src/kernel; pwd`
fi

if test -n "${cygnus_src}"; then
  mkdir -p src/binutils
  # Pull binutils source out of the whole cygnus repo.
  # Exclude top level dirs that we don't need to build.
  rsync -rptgoL --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    --exclude /blt \
    --exclude /compile \
    --exclude /contrib \
    --exclude /dejagnu \
    --exclude /elfcpp \
    --exclude /expect \
    --exclude /gdb \
    --exclude /gold \
    --exclude /itcl \
    --exclude /iwidgets \
    --exclude /libdecnumber \
    --exclude /libgloss \
    --exclude /libgui \
    --exclude /mmalloc \
    --exclude /newlib \
    --exclude /rda \
    --exclude /readline \
    --exclude /sid \
    --exclude /sim \
    --exclude /tcl \
    --exclude /tk \
    --exclude /utils \
    --exclude /winsup \
    "${cygnus_src}"/ src/binutils
  binutils_src=`cd src/binutils; pwd`

  mkdir -p src/gdb
  # Pull gdb source out of the whole cygnus repo.  Exclude some top level
  # dirs, and some under gdb;  gdbtk is old stuff we don't want.
  rsync -rptgoL --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    --exclude /binutils \
    --exclude /blt \
    --exclude /cgen \
    --exclude /compile \
    --exclude /contrib \
    --exclude /dejagnu \
    --exclude /elfcpp \
    --exclude /expect \
    --exclude /gas \
    --exclude /gdb/gdbtk \
    --exclude /gdb/testsuite/gdb.gdbtk \
    --exclude /gold \
    --exclude /gprof \
    --exclude /intl \
    --exclude /itcl \
    --exclude /iwidgets \
    --exclude /ld \
    --exclude /libgloss \
    --exclude /libgui \
    --exclude /mmalloc \
    --exclude /newlib \
    --exclude /rda \
    --exclude /sid \
    --exclude /tcl \
    --exclude /tk \
    --exclude /utils \
    --exclude /winsup \
    "${cygnus_src}"/ src/gdb
  gdb_src=`cd src/gdb; pwd`

else

  if test -n "${binutils_src}"; then
    mkdir -p src/binutils
    rsync -rptgo --delete \
      --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
      "${binutils_src}"/ src/binutils/
    binutils_src=`cd src/binutils; pwd`
  fi

  if test -n "${gdb_src}"; then
    mkdir -p src/gdb
    rsync -rptgo --delete \
      --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
      "${gdb_src}"/ src/gdb/
    gdb_src=`cd src/gdb; pwd`
  fi

fi

if test -n "${gcc_src}"; then
  mkdir -p src/gcc
  rsync -rptgo --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    "${gcc_src}"/ src/gcc/
  gcc_src=`cd src/gcc; pwd`
fi

if test -n "${gmp_src}"; then
  mkdir -p src/gmp
  rsync -rptgo --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    "${gmp_src}"/ src/gmp/
  gmp_src=`cd src/gmp; pwd`
fi

if test -n "${mpfr_src}"; then
  mkdir -p src/mpfr
  rsync -rptgo --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    "${mpfr_src}"/ src/mpfr/
  mpfr_src=`cd src/mpfr; pwd`
fi

if test -n "${zlib_src}"; then
  mkdir -p src/zlib
  rsync -rptgo --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    "${zlib_src}"/ src/zlib/
  zlib_src=`cd src/zlib; pwd`
fi

if test -n "${ncurses_src}"; then
  mkdir -p src/ncurses
  rsync -rptgo --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    "${ncurses_src}"/ src/ncurses/
  ncurses_src=`cd src/ncurses; pwd`
fi

if test -n "${glibc_src}"; then
  mkdir -p src/glibc
  rsync -rptgo --delete \
    --exclude=CVS --exclude=.svn --exclude=\*~ --exclude=.\#\* \
    "${glibc_src}"/ src/glibc/
  glibc_src=`cd src/glibc; pwd`
fi

if test ! -d "${kernel_src}"; then
  echo "No kernel source!"
  exit 1
fi
if test ! -d "${binutils_src}"; then
  echo "No binutils source!"
  exit 1
fi
if test ! -d "${gcc_src}"; then
  echo "No gcc source!"
  exit 1
fi
if test ! -d "${glibc_src}"; then
  echo "No glibc source!"
  exit 1
fi
if test -n "${gdb_src}" && test ! -d "${ncurses_src}"; then
  echo "No ncurses source!"
  exit 1
fi


unset combined_src
if test x${combined_tree} = xyes; then
  # Use a combined source tree
  rm -rf src/combined
  mkdir -p src/combined
  cp -al "${binutils_src}"/* src/combined
  cp -alf "${gcc_src}"/* src/combined
  combined_src=`cd src/combined; pwd`
fi

# Depending on the version of autocont used, we may need to specify
# more than --build.
gcc_ht=yes
if test -f "${combined_src:-${gcc_src}}"/gcc/BASE-VER; then
  case `cat "${combined_src:-${gcc_src}}"/gcc/BASE-VER` in
    4.[3-9]* | [5-9].*) gcc_ht= ;;
  esac
fi

if test -n "${host_dest}"; then
  # host binutils+gcc build
  # We do this because glibc requires at least gcc-3.4, and the system
  # compiler may be older.  We also need host tools that support -msecure-plt.
  # NOTE!  This build must not use gcc sources hacked to provide -rpath

  if test -z "${combined_src}"; then
    rm -rf build/host_bin
    mkdir -p build/host_bin
    cd build/host_bin

    CFLAGS="-g -O" CXXFLAGS="-g -O" "${binutils_src}"/configure \
      --build=powerpc-linux \
      --enable-targets=powerpc64-linux \
      --prefix="${host_dest}" \
      --disable-nls \
      >& _configure
    make >& _make
    make install >& _install
    cd ../..
  fi

  rm -rf build/host_gcc
  mkdir -p build/host_gcc
  cd build/host_gcc

  CFLAGS="-g -O" CXXFLAGS="-g -O" "${combined_src:-${gcc_src}}"/configure \
    --build=powerpc-linux \
    ${gcc_ht:+ --host=powerpc-linux --target=powerpc-linux} \
    --enable-targets=powerpc64-linux \
    --prefix="${host_dest}" \
    --with-long-double-128 \
    --enable-__cxa_atexit \
    --enable-languages=c \
    --enable-shared \
    --disable-nls \
    >& _configure
  make STAGE1_CFLAGS="-g -O" bootstrap >& _make
  make install >& _install
  cd ../..

  # Sanity check the ld we just built
  if ! "$gcc_ld" --help 2>&1 | grep -q bss-plt; then
    echo "$gcc_ld is too old!"
    exit 1
  fi

  PATH="${host_dest}/bin:$PATH"
fi


# Hack the gcc source so that binaries generated will be able to use
# the new glibc.  This isn't necessary (or desirable) when building
# a cross-compiler because with a cross-compiler you would be running
# the binaries on another system, which presumably would have glibc
# installed in the usual place.  It is also possible to hack the gcc
# specs file after gcc is built instead of editing the source, but that
# presents a problem when trying to bootstrap gcc.  A gcc bootstrap is
# a multi-stage process, and you'd need to hack specs after each stage.
# It is not possible to simply set LD_LIBRARY_PATH in the environment
# because existing dynamic apps would then try to use the old ld.so
# with the new libc.so.  This fails miserably.

# Add -rpath to where new shared libs will be installed, and modify
# --dynamic-linker to point there too.  Use new dtags so that we get
# DT_RUNPATH in binaries rather than DT_RPATH.  DT_RPATH can't be overridden
# with LD_LIBRARY_PATH.
s1='/#define LINK_OS_LINUX_SPEC[3264]* "-m/,/^$/s@-m elf\([64]*\)\([^ ]*\) %{!shared: %{!static:@-m elf\1\2 %{!static: --enable-new-dtags -rpath '"${dest}"'/lib\1:'"${dest}"'/usr/lib\1 %{!shared:@'
s2='/#define LINK_OS_LINUX_SPEC[3264]* "-m/,/^$/s@\(-dynamic-linker \)\(/lib[^/]*\)@\1'"${dest}"'\2@'
s3='s@\(#define GLIBC_DYNAMIC_LINKER[3264]* "\)@\1'"${dest}"@
for f in "${combined_src:-${gcc_src}}"/gcc/config/rs6000/{linux64.h,sysv4.h}
do
  sed -e "$s1" -e "$s2" -e "$s3" < "$f" > tmp.$$ \
    && { cmp -s tmp.$$ "$f" || mv -f tmp.$$ "$f"; } || exit 1
  rm -f tmp.$$
done


# Hack the glibc source so that the -rpath option we add on all shared libs
# and executable won't bomb ld.so, which checks that -rpath is not given.
s1='s@assert (\(info\[DT_R.*PATH\]\) == NULL)@\1 = NULL@'
for f in "${glibc_src}"/elf/dynamic-link.h
do
  sed -e "$s1" < "$f" > tmp.$$ \
    && { cmp -s tmp.$$ "$f" || mv -f tmp.$$ "$f"; } || exit 1
  rm -f tmp.$$
done


# kernel headers.

( cd "${kernel_src}"
  yes "" | make ARCH=powerpc oldconfig \
                include/linux/autoconf.h include/linux/version.h >& _make
)

rm -rf "${dest}"/usr/include/{linux,asm,asm-generic,asm-ppc,asm-ppc64,asm-powerpc}
mkdir -p "${dest}"/usr/include
cp -a "${kernel_src}"/include/linux "${dest}"/usr/include/linux
cp -a "${kernel_src}"/include/asm-generic "${dest}"/usr/include/asm-generic
cp -a "${kernel_src}"/include/asm-ppc "${dest}"/usr/include/asm-ppc
if test -d "${kernel_src}"/include/asm-powerpc; then
  cp -a "${kernel_src}"/include/asm-powerpc "${dest}"/usr/include/asm-powerpc
  ln -s asm-powerpc "${dest}"/usr/include/asm
else
  cp -a "${kernel_src}"/include/asm-ppc64 "${dest}"/usr/include/asm-ppc64
  mkdir -p "${dest}"/usr/include/asm
  ( cd "${dest}"/usr/include/asm-ppc64
    header_list="$(/bin/ls *.h)"
    cd ../asm
    for header in ${header_list}; do
      rm -f ${header}
      macro=$(echo ${header} |
        sed 'y/.abcdefghijklmnopqrstuvwzyz/_ABCDEFGHIJKLMNOPQRSTUVWXYZ/')

      cat >> ${header} <<EOF
#ifndef __ASM_STUB_${macro}__
# define __ASM_STUB_${macro}__
# if defined __powerpc64__
#  include <asm-ppc64/${header}>
# elif defined __powerpc__
#  include <asm-ppc/${header}>
# endif
#endif
EOF
    done
  )
fi


## glibc headers
## This used to be needed for building gcc, because gcc used signal.h
## and sys/ucontext.h during powerpc libgcc build.  With newer gcc
## this dependency has been removed.  In any case, installing headers
## that don't correspond to the installed libc is dangerous.  Compiling
## code using glibc headers with long double printf support result in
## link errors when using an older system glibc without such support.
## Which breaks the first binutils configure.
#
#rm -rf build/glibc
#mkdir -p build/glibc
#cd build/glibc
#
#"${glibc_src}"/configure \
#  --build=powerpc-linux \
#  --host=powerpc64-linux \
#  --prefix="${dest}" \
#  --with-headers="${dest}"/usr/include \
#  --disable-sanity-checks \
#  --without-cvs \
#  >& _configure
#
#make sysdeps/gnu/errlist.c >& _make
#mkdir -p stdio-common
#touch stdio-common/errlist-compat.c
#make install-headers >& _install
#
## Some headers aren't installed by install-headers, so do them by hand.
#mkdir -p "${dest}"/usr/include/gnu
#
#if test ! -f "${dest}"/usr/include/gnu/stubs.h; then
#  touch "${dest}"/usr/include/gnu/stubs.h
#fi
#if test ! -f "${dest}"/usr/include/gnu/stubs-32.h; then
#  touch "${dest}"/usr/include/gnu/stubs-32.h
#fi
#if test ! -f "${dest}"/usr/include/gnu/stubs-64.h; then
#  touch "${dest}"/usr/include/gnu/stubs-64.h
#fi
#if test ! -f "${dest}"/usr/include/features.h; then
#  cp "${glibc_src}"/include/features.h "${dest}"/usr/include/features.h
#fi
#if test ! -f "${dest}"/usr/include/bits/stdio_lim.h; then
#  cp bits/stdio_lim.h "${dest}"/usr/include/bits/stdio_lim.h
#fi
#cd ../..


# If we don't have a system limits.h, gcc will install a version that
# doesn't have the facility to include the system limits.h.
test -e "${dest}"/usr/include/limits.h || touch "${dest}"/usr/include/limits.h


# first binutils+gcc build
# This can't be a "make bootstrap" because we don't have glibc installed yet.

if test -z "${combined_src}"; then
  rm -rf build/bin
  mkdir -p build/bin
  cd build/bin

  CFLAGS="-g -O" CXXFLAGS="-g -O" "${binutils_src}"/configure \
    --build=powerpc-linux \
    --enable-targets=powerpc64-linux \
    --with-sysroot="${dest}" \
    --prefix=/usr \
    --disable-nls \
    >& _configure
  make >& _make
  make DESTDIR="${dest}" install >& _install
  cd ../..
fi

rm -rf build/gcc
mkdir -p build/gcc
cd build/gcc

AS="$gcc_as" LD="$gcc_ld" \
"${combined_src:-${gcc_src}}"/configure \
  --build=powerpc-linux \
  ${gcc_ht:+ --host=powerpc-linux --target=powerpc-linux} \
  --enable-targets=powerpc64-linux \
  --with-sysroot="${dest}" \
  --prefix=/usr \
  --with-newlib \
  --with-long-double-128 \
  --enable-secureplt \
  --disable-shared \
  --disable-threads \
  --disable-libmudflap \
  --disable-libssp \
  --disable-libgomp \
  --enable-decimal-float=no \
  --disable-bootstrap \
  --enable-languages=c \
  >& _configure
make >& _make
make DESTDIR="${dest}" install >& _install
cd ../..


# Install powerpc-linux-* and powerpc64-linux-* aliases for our new tools
# This is in case these already exist somewhere on the system.  Many
# configure scripts prefer to use eg. "powerpc-linux-as" over plain "as".
#
( cd "${dest}"/usr/bin
  for z in addr2line ar as c++filt ld nm objcopy objdump ranlib size strings strip
  do
    test -x $z && test ! -e powerpc-linux-$x && ln -sfn $z powerpc-linux-$z
  done
  for z in addr2line ar c++filt nm objcopy objdump ranlib size strings strip
  do
    test -x $z && test ! -e powerpc64-linux-$x && ln -sfn $z powerpc64-linux-$z
  done
  if test ! -e powerpc64-linux-as; then
    cat > powerpc64-linux-as <<EOF
#! /bin/sh
exec ${dest}/usr/bin/as -a64 "\$@"
EOF
    chmod a+x powerpc64-linux-as
  fi
  if test ! -e powerpc64-linux-ld; then
    cat > powerpc64-linux-ld <<EOF
#! /bin/sh
exec ${dest}/usr/bin/ld -melf64ppc "\$@"
EOF
    chmod a+x powerpc64-linux-ld
  fi
  if test ! -e powerpc64-linux-gcc; then
    cat > powerpc64-linux-gcc <<EOF
#! /bin/sh
case " \$@ " in
*" -m32 "*) p= ;;
" -V "*) shift; p="-V \$1 -m64 "; shift;;
" -V"*) p="\$1 -m64 "; shift;;
*) p="-m64 ";;
esac
exec ${dest}/usr/bin/gcc \${p}"\$@"
EOF
    chmod a+x powerpc64-linux-gcc
  fi
)


# first ppc32 glibc build
# We can't use the newly built gcc to compile glibc because it will set the
# dynamic linker to be ${dest}/lib/ld.so.1, which isn't installed until the
# glibc build finishes.  So trying to run anything compiled with the new gcc
# will fail, in particular, glibc configure tests.  I suppose you might be
# able to supply glibc configure with lots of libc_cv_* variables to
# avoid this, but then you'd forever be changing this script to keep up with
# new glibc configure tests.
# Note that dynamically linked programs built here with the old host gcc are
# subtly broken too;  The glibc build sets their dynamic linker to
# ${dest}/lib/ld.so.1 but doesn't provide rpath.  Which means you'll get the
# new ld.so trying to use the system libc.so, which doesn't work.  ld.so and
# libc.so share data structures so are tightly coupled.  To run the new
# programs, you need to set LD_LIBRARY_PATH for them, or better (so as to not
# affect forked commands that might need the system libs), run ld.so.1
# explicitly, passing --library-path as is done for localedef below.
# This is one of the reasons why you need to build glibc twice.

rm -rf build/glibc32
mkdir -p build/glibc32
cd build/glibc32

echo slibdir="${dest}"/lib > configparms
echo sysconfdir="${dest}"/etc >> configparms
echo rootsbindir="${dest}"/sbin >> configparms

CC="gcc -msecure-plt" \
"${glibc_src}"/configure \
  --build=powerpc-linux \
  --host=powerpc-linux \
  --prefix="${dest}/usr" \
  --with-headers="${dest}"/usr/include \
  --enable-add-ons=nptl \
  --with-tls \
  --without-cvs \
  --enable-kernel=2.6.25 \
  >& _configure
make >& _make
make install >& _install
cd ../..

if test ! -f "${dest}"/etc/ld.so.conf; then
  cat > "${dest}"/etc/ld.so.conf <<EOF
${dest}/usr/powerpc-linux/lib
${dest}/usr/powerpc-linux/lib64
${dest}/lib
${dest}/lib64
${dest}/usr/lib
${dest}/usr/lib64
/usr/powerpc-linux/lib
/usr/powerpc64-linux/lib
/lib
/lib64
/usr/lib
/usr/lib64
EOF
fi
"${dest}"/sbin/ldconfig

# Build locale files.
# Needed for libstdc++ configure in the full GCC build below
mkdir -p "${dest}"/usr/lib/locale
sed -n -e '/SUPPORTED-LOCALES/,$ s@\([^/]*\)/\([^ \\]*\).*@\1 \2@p' \
 < "${glibc_src}"/localedata/SUPPORTED | sort | \
while read l c x; do
  echo localedef -i ${l%\.*} -f $c $l
  "${dest}"/lib/ld.so.1 --library-path "${dest}"/lib \
    "${dest}"/usr/bin/localedef -i ${l%\.*} -f $c $l || true
done

# glibc isn't aware of sysroot, and so sets the full path in GROUP
# statements in libc.so.  Our sysrooted ld only wants the path
# below the sysroot.
for f in "${dest}"/usr/lib/{libc.so,libpthread.so}; do
  sed -e "s@${dest}@@g" < "$f" > tmp.$$ \
    && { cmp -s tmp.$$ "$f" || mv -f tmp.$$ "$f"; } || exit 1
  rm -f tmp.$$
done


# Now set PATH to include the newly built toolchain.
PATH="${dest}/usr/bin:$PATH"


# Hack around a glibc build problem.  gcc has been built static-only,
# so libgcc_eh.a isn't built and all the libgcc_eh functions are in
# libgcc.a.  Yet glibc wants to link with libgcc_eh.a
for z in `find "${dest}"/usr/lib -name libgcc.a`; do
  test -e ${z%\.a}_eh.a || ln -s libgcc.a ${z%\.a}_eh.a
done


# first ppc64 glibc build

rm -rf build/glibc64
mkdir -p build/glibc64
cd build/glibc64

# We want shared libs in ${dest}/lib64, and we don't want to trample on
# any 32-bit binaries.
echo slibdir="${dest}"/lib64 > configparms
echo sysconfdir="${dest}"/etc >> configparms
echo bindir="${dest}"/usr/bin64 >> configparms
echo sbindir="${dest}"/usr/sbin64 >> configparms
echo rootsbindir="${dest}"/sbin64 >> configparms
echo localedir="${dest}"/usr/lib >> configparms

# We know the compiler we are using supports everything glibc needs,
# but glibc can't run all its configure tests because a 64-bit glibc isn't
# yet installed.  So tell configure some answers.
libc_cv_forced_unwind=yes \
libc_cv_c_cleanup=yes \
"${glibc_src}"/configure \
    --build=powerpc-linux \
    --host=powerpc64-linux \
    --prefix="${dest}/usr" \
    --libdir="${dest}"/usr/lib64 \
    --libexecdir="${dest}"/usr/libexec64 \
    --with-headers="${dest}"/usr/include \
    --enable-add-ons=nptl \
    --with-tls \
    --without-cvs \
    --enable-kernel=2.6.25 \
    >& _configure
make >& _make
make install >& _install
cd ../..

# Build locale files.
#mkdir -p "${dest}"/usr/lib64/locale
#sed -n -e '/SUPPORTED-LOCALES/,$ s@\([^/]*\)/\([^ \\]*\).*@\1 \2@p' \
# < "${glibc_src}"/localedata/SUPPORTED | sort | \
#while read l c x; do
#  echo localedef -i ${l%\.*} -f $c $l
#  "${dest}"/usr/bin64/localedef -i ${l%\.*} -f $c $l || true
#done

for f in "${dest}"/usr/lib64/{libc.so,libpthread.so}; do
  sed -e "s@${dest}@@g" < "$f" > tmp.$$ \
    && { cmp -s tmp.$$ "$f" || mv -f tmp.$$ "$f"; } || exit 1
  rm -f tmp.$$
done


# GMP and MPFR support libraries need to be installed in sysroot.
if test -n "${gmp_src}"; then
  rm -rf build/gmp
  mkdir -p build/gmp
  cd build/gmp

  "${gmp_src}"/configure \
      --build=powerpc-linux \
      --prefix="${dest}"/usr \
      >& _configure
  make >& _make
  make install >& _install
  cd ../..
fi

if test -n "${mpfr_src}"; then
  rm -rf build/mpfr
  mkdir -p build/mpfr
  cd build/mpfr

  "${mpfr_src}"/configure \
      --build=powerpc-linux \
      --prefix="${dest}"/usr \
      --with-gmp="${dest}"/usr \
      >& _configure
  make >& _make
  make install >& _install
  cd ../..
fi

if test -n "${zlib_src}"; then
  rm -rf build/zlib
  mkdir -p build/zlib
  cd build/zlib
  cp -a "${zlib_src}"/* .

  ./configure \
      --prefix="${dest}"/usr \
      --shared \
      >& _configure
  make >& _make
  make install >& _install
  cd ../..
fi


# second binutils+gcc build
# This time we build a full compiler.  Pass AS and LD to configure,
# because configure isn't clever enough to find the right as and ld

if test -z "${combined_src}"; then
  rm -rf build/bin_1
  mv build/bin build/bin_1
  mkdir -p build/bin
  cd build/bin
  CFLAGS="-g -O" CXXFLAGS="-g -O" "${binutils_src}"/configure \
    --build=powerpc-linux \
    --enable-targets=powerpc64-linux \
    --with-sysroot="${dest}" \
    --prefix=/usr \
    --disable-nls \
    >& _configure
  make >& _make
  make DESTDIR="${dest}" install >& _install
  cd ../..
fi

rm -rf build/gcc_1
mv build/gcc build/gcc_1
mkdir -p build/gcc
cd build/gcc

AS="${dest}"/usr/bin/as \
LD="${dest}"/usr/bin/ld \
"${combined_src:-${gcc_src}}"/configure \
    --build=powerpc-linux \
    ${gcc_ht:+ --host=powerpc-linux --target=powerpc-linux} \
    --enable-targets=powerpc64-linux \
    --with-sysroot="${dest}" \
    --prefix=/usr \
    --with-long-double-128 \
    --enable-secureplt \
    --enable-__cxa_atexit \
    --enable-shared \
    --enable-languages=all \
    --enable-decimal-float \
    --enable-threads=posix \
    --enable-clocale=gnu \
    --enable-ssp \
    --enable-libstdcxx-allocator=new \
    --enable-checking=yes,rtl \
    >& _configure
make STAGE1_CFLAGS="-g -O" bootstrap >& _make
make DESTDIR="${dest}" install >& _install
cd ../..

( cd "${dest}"/usr/bin
  if test -x powerpc-linux-g++; then
    if test ! -e powerpc64-linux-g++; then
      cat > powerpc64-linux-g++ <<EOF
#! /bin/sh
case " \$@ " in
*" -m32 "*) p= ;;
" -V "*) shift; p="-V \$1 -m64 "; shift;;
" -V"*) p="\$1 -m64 "; shift;;
*) p="-m64 ";;
esac
exec ${dest}/usr/bin/g++ \${p}"\$@"
EOF
      chmod a+x powerpc64-linux-g++
    fi
    ln -f powerpc64-linux-g++ powerpc64-linux-c++
  fi
)


# second ppc32 glibc build

rm -rf build/glibc32_1
mv build/glibc32 build/glibc32_1
mkdir -p build/glibc32
cd build/glibc32

echo slibdir="${dest}"/lib > configparms
echo sysconfdir="${dest}"/etc >> configparms
echo rootsbindir="${dest}"/sbin >> configparms

"${glibc_src}"/configure \
    --build=powerpc-linux \
    --prefix="${dest}/usr" \
    --with-headers="${dest}"/usr/include \
    --enable-add-ons=nptl \
    --with-tls \
    --without-cvs \
    --enable-kernel=2.6.25 \
    >& _configure
make >& _make
make install >& _install
cd ../..

for f in "${dest}"/usr/lib/{libc.so,libpthread.so}; do
  sed -e "s@${dest}@@g" < "$f" > tmp.$$ \
    && { cmp -s tmp.$$ "$f" || mv -f tmp.$$ "$f"; } || exit 1
  rm -f tmp.$$
done


# second ppc64 glibc build
# This is hardly necessary, since we built ppc64 glibc using the new gcc in
# the first build.  However, we fudge glibc configure params here to say we
# aren't really cross-compiling, which lets us build a few more parts of
# glibc.

rm -rf build/glibc64_1
mv build/glibc64 build/glibc64_1
mkdir -p build/glibc64
cd build/glibc64

# We want shared libs in ${dest}/lib64, and we don't want to trample on
# any 32-bit binaries.  Also say that we can run 64-bit binaries (assuming
# ppc64 hardware!).
echo slibdir="${dest}"/lib64 > configparms
echo sysconfdir="${dest}"/etc >> configparms
echo bindir="${dest}"/usr/bin64 >> configparms
echo sbindir="${dest}"/usr/sbin64 >> configparms
echo rootsbindir="${dest}"/sbin64 >> configparms
echo localedir="${dest}"/usr/lib >> configparms
echo cross-compiling=no >> configparms

"${glibc_src}"/configure \
    --build=powerpc-linux \
    --host=powerpc64-linux \
    --prefix="${dest}/usr" \
    --libdir="${dest}"/usr/lib64 \
    --libexecdir="${dest}"/usr/libexec64 \
    --with-headers="${dest}"/usr/include \
    --enable-add-ons=nptl \
    --with-tls \
    --without-cvs \
    --enable-kernel=2.6.25 \
    >& _configure
make >& _make
make install >& _install
cd ../..

for f in "${dest}"/usr/lib64/{libc.so,libpthread.so}; do
  sed -e "s@${dest}@@g" < "$f" > tmp.$$ \
    && { cmp -s tmp.$$ "$f" || mv -f tmp.$$ "$f"; } || exit 1
  rm -f tmp.$$
done


# ncurses library, needed for gdb
if test -n "${ncurses_src}"; then
  rm -rf build/ncurses
  mkdir -p build/ncurses
  cd build/ncurses
  "${ncurses_src}"/configure \
    --build=powerpc-linux \
    --prefix=${dest}/usr \
    --with-shared \
    --without-debug \
    >& _configure
  make >& _make
  make install >& _install
  cd ../..

  rm -rf build/ncurses64
  mkdir -p build/ncurses64
  cd build/ncurses64
  "${ncurses_src}"/configure \
    --build=powerpc-linux \
    --host=powerpc64-linux \
    --prefix="${dest}/usr" \
    --bindir="${dest}"/usr/bin64 \
    --sbindir="${dest}"/usr/sbin64 \
    --libexecdir="${dest}"/usr/libexec64 \
    --libdir="${dest}"/usr/lib64 \
    --with-shared \
    --without-debug \
    --with-bool="unsigned char"
    >& _configure
  make >& _make
  make install >& _install
  cd ../..
fi


# ppc gdb build

if test -n "${gdb_src}"; then
  rm -rf build/gdb32
  mkdir -p build/gdb32
  cd build/gdb32

  "${gdb_src}"/configure \
    --build=powerpc-linux \
    --with-sysroot="${dest}" \
    --prefix=/usr \
    --program-suffix=32 \
    --disable-tcl \
    --disable-tui \
    >& _configure
  make >& _make
  make DESTDIR="${dest}" install >& _install
  cd ../..
fi


# ppc64 gdb build

if test -n "${gdb_src}"; then
  rm -rf build/gdb64
  mkdir -p build/gdb64
  cd build/gdb64

  "${gdb_src}"/configure \
    --build=powerpc-linux \
    --host=powerpc64-linux \
    --with-sysroot="${dest}" \
    --prefix=/usr \
    --libdir=/usr/lib64 \
    --program-suffix=64 \
    --disable-tcl \
    --disable-tui \
    >& _configure
  make >& _make
  make DESTDIR="${dest}" install >& _install
  cd ../..
fi


More information about the Binutils mailing list