summaryrefslogtreecommitdiff
path: root/scripts/crosstool.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/crosstool.sh')
-rwxr-xr-xscripts/crosstool.sh299
1 files changed, 207 insertions, 92 deletions
diff --git a/scripts/crosstool.sh b/scripts/crosstool.sh
index cd068a6..d12654e 100755
--- a/scripts/crosstool.sh
+++ b/scripts/crosstool.sh
@@ -28,7 +28,7 @@ CT_STAR_DATE=`CT_DoDate +%s%N`
CT_STAR_DATE_HUMAN=`CT_DoDate +%Y%m%d.%H%M%S`
# Log to a temporary file until we have built our environment
-CT_ACTUAL_LOG_FILE="`pwd`/$$.log"
+CT_ACTUAL_LOG_FILE="${CT_TOP_DIR}/$$.log"
# CT_TOP_DIR should be an absolute path.
CT_TOP_DIR="`CT_MakeAbsolutePath \"${CT_TOP_DIR}\"`"
@@ -73,6 +73,9 @@ fi
# Yes! We can do full logging from now on!
CT_DoLog INFO "Build started ${CT_STAR_DATE_HUMAN}"
+# renice oursleves
+renice ${CT_NICE} $$ |CT_DoLog DEBUG
+
# Some sanity checks in the environment and needed tools
CT_DoLog INFO "Checking environment sanity"
@@ -109,50 +112,8 @@ CT_EndStep
CT_DoLog INFO "Building environment variables"
-# This should go in buildToolchain.sh, but we might need it because it could
-# be used by the user in his/her paths definitions.
# Target triplet: CT_TARGET needs a little love:
-case "${CT_ARCH_BE},${CT_ARCH_LE}" in
- y,) target_endian_eb=eb; target_endian_el=;;
- ,y) target_endian_eb=; target_endian_el=el;;
-esac
-case "${CT_ARCH}" in
- arm) CT_TARGET="${CT_ARCH}${target_endian_eb}";;
- mips) CT_TARGET="${CT_ARCH}${target_endian_el}";;
- x86*) # Much love for this one :-(
- # Ultimately, we should use config.sub to output the correct
- # procesor name. Work for later...
- arch="${CT_ARCH_ARCH}"
- [ -z "${arch}" ] && arch="${CT_ARCH_TUNE}"
- case "${CT_ARCH}" in
- x86_64) CT_TARGET=x86_64;;
- *) case "${arch}" in
- "") CT_TARGET=i386;;
- i386|i486|i586|i686) CT_TARGET="${arch}";;
- winchip*) CT_TARGET=i486;;
- pentium|pentium-mmx|c3*) CT_TARGET=i586;;
- nocona|athlon*64|k8|athlon-fx|opteron) CT_TARGET=x86_64;;
- pentiumpro|pentium*|athlon*) CT_TARGET=i686;;
- *) CT_TARGET=i586;;
- esac;;
- esac;;
-esac
-case "${CT_TARGET_VENDOR}" in
- "") CT_TARGET="${CT_TARGET}-unknown";;
- *) CT_TARGET="${CT_TARGET}-${CT_TARGET_VENDOR}";;
-esac
-case "${CT_KERNEL}" in
- linux*) CT_TARGET="${CT_TARGET}-linux";;
- cygwin*) CT_TARGET="${CT_TARGET}-cygwin";;
-esac
-case "${CT_LIBC}" in
- glibc) CT_TARGET="${CT_TARGET}-gnu";;
- uClibc) CT_TARGET="${CT_TARGET}-uclibc";;
-esac
-case "${CT_ARCH_ABI}" in
- eabi) CT_TARGET="${CT_TARGET}eabi";;
-esac
-CT_TARGET="`${CT_TOP_DIR}/tools/config.sub ${CT_TARGET}`"
+CT_DoBuildTargetTriplet
# Now, build up the variables from the user-configured options.
CT_KERNEL_FILE="${CT_KERNEL}-${CT_KERNEL_VERSION}"
@@ -171,84 +132,238 @@ CT_LIBC_FILE="${CT_LIBC}-${CT_LIBC_VERSION}"
# then rescan the options file now:
. "${CT_TOP_DIR}/.config"
-# Determine build system if not set by the user
-CT_Test "You did not specify the build system. Guessing." -z "${CT_BUILD}"
-CT_BUILD="`${CT_TOP_DIR}/tools/config.sub \"${CT_BUILD:-\`${CT_TOP_DIR}/tools/config.guess\`}\"`"
+# Some more sanity checks now that we have all paths set up
+case "${CT_TARBALLS_DIR},${CT_SRC_DIR},${CT_BUILD_DIR},${CT_PREFIX_DIR},${CT_INSTALL_DIR}" in
+ *" "*) CT_Abort "Don't use spaces in paths, it breaks things.";;
+esac
+
+# Note: we'll always install the core compiler in its own directory, so as to
+# not mix the two builds: core and final. Anyway, its generic, wether we use
+# a different compiler as core, or not.
+CT_CC_CORE_PREFIX_DIR="${CT_BUILD_DIR}/${CT_CC}-core"
+
+# Good, now grab a bit of informations on the system we're being run,
+# just in case something goes awok, and it's not our fault:
+CT_SYS_HOSTNAME=`hostname -f 2>/dev/null || true`
+# Hmmm. Some non-DHCP-enabled machines do not have an FQDN... Fall back to node name.
+CT_SYS_HOSTNAME="${CT_SYS_HOSTNAME:-`uname -n`}"
+CT_SYS_KERNEL=`uname -s`
+CT_SYS_REVISION=`uname -r`
+# MacOS X lacks '-o' :
+CT_SYS_OS=`uname -o || echo "Unknown (maybe MacOS-X)"`
+CT_SYS_MACHINE=`uname -m`
+CT_SYS_PROCESSOR=`uname -p`
+CT_SYS_USER="`id -un`"
+CT_SYS_DATE=`CT_DoDate +%Y%m%d.%H%M%S`
+CT_SYS_GCC=`gcc -dumpversion`
+CT_TOOLCHAIN_ID="crosstool-${CT_VERSION} build ${CT_SYS_DATE} by ${CT_SYS_USER}@${CT_SYS_HOSTNAME} for ${CT_TARGET}"
+
+# Check now if we can write to the destination directory:
+if [ -d "${CT_INSTALL_DIR}" ]; then
+ CT_TestAndAbort "Destination directory \"${CT_INSTALL_DIR}\" is not removable" ! -w `dirname "${CT_INSTALL_DIR}"`
+fi
# Get rid of pre-existing installed toolchain and previous build directories.
# We need to do that _before_ we can safely log, because the log file will
# most probably be in the toolchain directory.
-if [ -d "${CT_PREFIX_DIR}" ]; then
- mv "${CT_PREFIX_DIR}" "${CT_PREFIX_DIR}.$$"
- nohup rm -rf "${CT_PREFIX_DIR}.$$" >/dev/null 2>&1 &
+if [ -d "${CT_INSTALL_DIR}" ]; then
+ mv "${CT_INSTALL_DIR}" "${CT_INSTALL_DIR}.$$"
+ nohup rm -rf "${CT_INSTALL_DIR}.$$" >/dev/null 2>&1 &
fi
-mkdir -p "${CT_PREFIX_DIR}"
if [ -d "${CT_BUILD_DIR}" ]; then
mv "${CT_BUILD_DIR}" "${CT_BUILD_DIR}.$$"
nohup rm -rf "${CT_BUILD_DIR}.$$" >/dev/null 2>&1 &
fi
+if [ "${CT_FORCE_EXTRACT}" = "y" -a -d "${CT_SRC_DIR}" ]; then
+ mv "${CT_SRC_DIR}" "${CT_SRC_DIR}.$$"
+ nohup rm -rf "${CT_SRC_DIR}.$$" >/dev/null 2>&1 &
+fi
+mkdir -p "${CT_INSTALL_DIR}"
mkdir -p "${CT_BUILD_DIR}"
+mkdir -p "${CT_TARBALLS_DIR}"
+mkdir -p "${CT_SRC_DIR}"
-# Check now if we can write to the destination directory:
-if [ -d "${CT_PREFIX_DIR}" ]; then
- CT_TestAndAbort "Destination directory \"${CT_INSTALL_DIR}\" is not writeable" ! -w "${CT_PREFIX_DIR}"
-else
- mkdir -p "${CT_PREFIX_DIR}" || CT_Abort "Could not create destination directory \"${CT_PREFIX_DIR}\""
-fi
+# Make all path absolute, it so much easier!
+# Now we have had the directories created, we even will get rid of embedded .. in paths:
+CT_SRC_DIR="`CT_MakeAbsolutePath \"${CT_SRC_DIR}\"`"
+CT_TARBALLS_DIR="`CT_MakeAbsolutePath \"${CT_TARBALLS_DIR}\"`"
# Redirect log to the actual log file now we can
-# It's quite understandable that the log file will be installed in the
-# install directory, so we must first ensure it exists and is writeable (above)
-# before we can log there
-t="${CT_ACTUAL_LOG_FILE}"
+# It's quite understandable that the log file will be installed in the install
+# directory, so we must first ensure it exists and is writeable (above) before
+# we can log there
case "${CT_LOG_TO_FILE},${CT_LOG_FILE}" in
- ,*) CT_ACTUAL_LOG_FILE=/dev/null
- rm -f "${t}"
+ ,*) rm -f "${CT_ACTUAL_LOG_FILE}"
+ CT_ACTUAL_LOG_FILE=/dev/null
;;
y,/*) mkdir -p "`dirname \"${CT_LOG_FILE}\"`"
+ mv "${CT_ACTUAL_LOG_FILE}" "${CT_LOG_FILE}"
CT_ACTUAL_LOG_FILE="${CT_LOG_FILE}"
- mv "${t}" "${CT_ACTUAL_LOG_FILE}"
;;
y,*) mkdir -p "`pwd`/`dirname \"${CT_LOG_FILE}\"`"
+ mv "${CT_ACTUAL_LOG_FILE}" "`pwd`/${CT_LOG_FILE}"
CT_ACTUAL_LOG_FILE="`pwd`/${CT_LOG_FILE}"
- mv "${t}" "${CT_ACTUAL_LOG_FILE}"
;;
esac
-# Some more sanity checks now that we have all paths set up
-case "${CT_TARBALLS_DIR},${CT_SRC_DIR},${CT_BUILD_DIR},${CT_PREFIX_DIR},${CT_INSTALL_DIR}" in
- *" "*) CT_Abort "Don't use spaces in paths, it breaks things.";;
+# Determine build system if not set by the user
+CT_Test "You did not specify the build system. Guessing." -z "${CT_BUILD}"
+CT_BUILD="`${CT_TOP_DIR}/tools/config.sub \"${CT_BUILD:-\`${CT_TOP_DIR}/tools/config.guess\`}\"`"
+
+# Arrange paths depending on wether we use sys-root or not.
+if [ "${CT_USE_SYSROOT}" = "y" ]; then
+ CT_SYSROOT_DIR="${CT_PREFIX_DIR}/${CT_TARGET}/sys-root"
+ CT_HEADERS_DIR="${CT_SYSROOT_DIR}/usr/include"
+ BINUTILS_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}"
+ CC_CORE_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}"
+ CC_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}"
+ LIBC_SYSROOT_ARG=""
+ # glibc's prefix must be exactly /usr, else --with-sysroot'd gcc will get
+ # confused when $sysroot/usr/include is not present.
+ # Note: --prefix=/usr is magic!
+ # See http://www.gnu.org/software/libc/FAQ.html#s-2.2
+else
+ # plain old way. All libraries in prefix/target/lib
+ CT_SYSROOT_DIR="${CT_PREFIX_DIR}/${CT_TARGET}"
+ CT_HEADERS_DIR="${CT_SYSROOT_DIR}/include"
+ # hack! Always use --with-sysroot for binutils.
+ # binutils 2.14 and later obey it, older binutils ignore it.
+ # Lets you build a working 32->64 bit cross gcc
+ BINUTILS_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}"
+ # Use --with-headers, else final gcc will define disable_glibc while
+ # building libgcc, and you'll have no profiling
+ CC_CORE_SYSROOT_ARG="--without-headers"
+ CC_SYSROOT_ARG="--with-headers=${CT_HEADERS_DIR}"
+ LIBC_SYSROOT_ARG="prefix="
+fi
+
+# Prepare the 'lib' directories in sysroot, else the ../lib64 hack used by
+# 32 -> 64 bit crosscompilers won't work, and build of final gcc will fail with
+# "ld: cannot open crti.o: No such file or directory"
+mkdir -p "${CT_SYSROOT_DIR}/lib"
+mkdir -p "${CT_SYSROOT_DIR}/usr/lib"
+
+# Canadian-cross are really picky on the way they are built. Tweak the values.
+if [ "${CT_CANADIAN}" = "y" ]; then
+ # Arrange so that gcc never, ever think that build system == host system
+ CT_CANADIAN_OPT="--build=`echo \"${CT_BUILD}\" |sed -r -e 's/-/-build_/'`"
+ # We shall have a compiler for this target!
+ # Do test here...
+else
+ CT_HOST="${CT_BUILD}"
+ CT_CANADIAN_OPT=
+ # Add the target toolchain in the path so that we can build the C library
+ export PATH="${CT_PREFIX_DIR}/bin:${CT_CC_CORE_PREFIX_DIR}/bin:${PATH}"
+fi
+
+# Modify GCC_HOST to never be equal to $BUILD or $TARGET
+# This strange operation causes gcc to always generate a cross-compiler
+# even if the build machine is the same kind as the host.
+# This is why CC has to be set when doing a canadian cross; you can't find a
+# host compiler by appending -gcc to our whacky $GCC_HOST
+# Kludge: it is reported that the above causes canadian crosses with cygwin
+# hosts to fail, so avoid it just in that one case. It would be cleaner to
+# just move this into the non-canadian case above, but I'm afraid that might
+# cause some configure script somewhere to decide that since build==host, they
+# could run host binaries.
+# (Copied almost as-is from original crosstool):
+case "${CT_KERNEL},${CT_CANADIAN}" in
+ cygwin,y) ;;
+ *) CT_HOST="`echo \"${CT_HOST}\" |sed -r -e 's/-/-host_/;'`";;
esac
-# Note: we'll always install the core compiler in its own directory, so as to
-# not mix the two builds: core and final. Anyway, its generic, wether we use
-# a different compiler as core, or not.
-CT_CC_CORE_PREFIX_DIR="${CT_BUILD_DIR}/${CT_CC}-core"
+# Ah! Recent versions of binutils need some of the build and/or host system
+# (read CT_BUILD and CT_HOST) tools to be accessible (ar is but an example).
+# Do that:
+CT_DoLog EXTRA "Making build system tools available"
+mkdir -p "${CT_PREFIX_DIR}/bin"
+for tool in ar; do
+ ln -s "`which ${tool}`" "${CT_PREFIX_DIR}/bin/${CT_BUILD}-${tool}"
+ ln -s "`which ${tool}`" "${CT_PREFIX_DIR}/bin/${CT_HOST}-${tool}"
+done
-# Good, now grab a bit of informations on the system we're being run,
-# just in case something goes awok, and it's not our fault:
-CT_SYS_HOSTNAME=`hostname -f 2>/dev/null || true`
-# Hmmm. Some non-DHCP-enabled machines do not have an FQDN... Fall back to node name.
-CT_SYS_HOSTNAME="${CT_SYS_HOSTNAME:-`uname -n`}"
-CT_SYS_KERNEL=`uname -s`
-CT_SYS_REVISION=`uname -r`
-# MacOS X lacks '-o' :
-CT_SYS_OS=`uname -o || echo Unkown`
-CT_SYS_MACHINE=`uname -m`
-CT_SYS_PROCESSOR=`uname -p`
-CT_SYS_USER="`id -un`"
-CT_SYS_DATE=`CT_DoDate +%Y%m%d.%H%M%S`
-CT_SYS_GCC=`gcc -dumpversion`
-CT_TOOLCHAIN_ID="crosstool-${CT_VERSION} build ${CT_SYS_DATE} by ${CT_SYS_USER}@${CT_SYS_HOSTNAME} for ${CT_TARGET}"
+# Ha. cygwin host have an .exe suffix (extension) for executables.
+[ "${CT_KERNEL}" = "cygwin" ] && EXEEXT=".exe" || EXEEXT=""
-# renice oursleves
-renice ${CT_NICE} $$ |CT_DoLog DEBUG
+# Transform the ARCH into a kernel-understandable ARCH
+case "${CT_ARCH}" in
+ x86) CT_KERNEL_ARCH=i386;;
+ ppc) CT_KERNEL_ARCH=powerpc;;
+ *) CT_KERNEL_ARCH="${CT_ARCH}";;
+esac
+
+# Build up the TARGET_CFLAGS from user-provided options
+# Override with user-specified CFLAGS
+[ -n "${CT_ARCH_CPU}" ] && CT_TARGET_CFLAGS="-mcpu=${CT_ARCH_CPU} ${CT_TARGET_CFLAGS}"
+[ -n "${CT_ARCH_TUNE}" ] && CT_TARGET_CFLAGS="-mtune=${CT_ARCH_TUNE} ${CT_TARGET_CFLAGS}"
+[ -n "${CT_ARCH_ARCH}" ] && CT_TARGET_CFLAGS="-march=${CT_ARCH_ARCH} ${CT_TARGET_CFLAGS}"
+[ -n "${CT_ARCH_FPU}" ] && CT_TARGET_CFLAGS="-mfpu=${CT_ARCH_FPU} ${CT_TARGET_CFLAGS}"
+
+# Help gcc
+CT_CFLAGS_FOR_HOST=
+[ "${CT_USE_PIPES}" = "y" ] && CT_CFLAGS_FOR_HOST="${CT_CFLAGS_FOR_HOST} -pipe"
+
+# And help make go faster
+PARALLELMFLAGS=
+[ ${CT_PARALLEL_JOBS} -ne 0 ] && PARALLELMFLAGS="${PARALLELMFLAGS} -j${CT_PARALLEL_JOBS}"
+[ ${CT_LOAD} -ne 0 ] && PARALLELMFLAGS="${PARALLELMFLAGS} -l${CT_LOAD}"
+
+CT_DoStep EXTRA "Dumping internal crosstool-NG configuration"
+CT_DoLog EXTRA "Building a toolchain for:"
+CT_DoLog EXTRA " build = ${CT_BUILD}"
+CT_DoLog EXTRA " host = ${CT_HOST}"
+CT_DoLog EXTRA " target = ${CT_TARGET}"
+set |egrep '^CT_.+=' |sort |CT_DoLog DEBUG
+CT_EndStep
# Include sub-scripts instead of calling them: that way, we do not have to
# export any variable, nor re-parse the configuration and functions files.
-. "${CT_TOP_DIR}/scripts/getExtractPatch.sh"
-. "${CT_TOP_DIR}/scripts/buildToolchain.sh"
-#. "${CT_TOP_DIR}/scripts/testToolchain.sh"
+. "${CT_TOP_DIR}/scripts/build/kernel_${CT_KERNEL}.sh"
+. "${CT_TOP_DIR}/scripts/build/binutils.sh"
+. "${CT_TOP_DIR}/scripts/build/libc_libfloat.sh"
+. "${CT_TOP_DIR}/scripts/build/libc_${CT_LIBC}.sh"
+. "${CT_TOP_DIR}/scripts/build/cc_core_${CT_CC_CORE}.sh"
+. "${CT_TOP_DIR}/scripts/build/cc_${CT_CC}.sh"
+
+# Now for the job by itself. Go have a coffee!
+if [ "${CT_NO_DOWNLOAD}" != "y" ]; then
+ CT_DoStep INFO "Retrieving needed toolchain components' tarballs"
+ do_kernel_get
+ do_binutils_get
+ do_libc_get
+ do_libfloat_get
+ do_cc_core_get
+ do_cc_get
+ CT_EndStep
+fi
+
+if [ "${CT_ONLY_DOWNLOAD}" != "y" ]; then
+ if [ "${CT_FORCE_EXTRACT}" = "y" ]; then
+ mv "${CT_SRC_DIR}" "${CT_SRC_DIR}.$$"
+ nohup rm -rf "${CT_SRC_DIR}.$$" >/dev/null 2>&1
+ fi
+ CT_DoStep INFO "Extracting and patching toolchain components"
+ do_kernel_extract
+ do_binutils_extract
+ do_libc_extract
+ do_libfloat_extract
+ do_cc_core_extract
+ do_cc_extract
+ CT_EndStep
+
+ if [ "${CT_ONLY_EXTRACT}" != "y" ]; then
+ do_libc_check_config
+ do_kernel_check_config
+ do_kernel_headers
+ do_binutils
+ do_libc_headers
+ do_cc_core
+ do_libfloat
+ do_libc
+ do_cc
+ do_libc_finish
+ fi
+fi
if [ -n "${CT_TARGET_ALIAS}" ]; then
CT_DoLog EXTRA "Creating symlinks from \"${CT_TARGET}-*\" to \"${CT_TARGET_ALIAS}-*\""