yann@1: #!/bin/bash yann@1: # Copyright 2007 Yann E. MORIN yann@1: # Licensed under the GPL v2. See COPYING in the root of this package. yann@1: yann@1: # This is the main entry point to crosstool yann@1: # This will: yann@1: # - download, extract and patch the toolchain components yann@1: # - build and install each components in turn yann@1: # - and eventually test the resulting toolchain yann@1: yann@1: # What this file does is prepare the environment, based upon the user-choosen yann@1: # options. It also checks the existing environment for un-friendly variables, yann@1: # and checks for needed tools. It eventually calls the main build script. yann@1: yann@1: # User must set CT_TOP_DIR in is environment! yann@1: # Once we can build out-of-tree, then this will have to go. yann@1: if [ -z "${CT_TOP_DIR}" -o ! -d "${CT_TOP_DIR}" ]; then yann@1: # We don't have the functions right now, because we don't have CT_TOP_DIR. yann@1: # Do the print stuff by hand: yann@1: echo "CT_TOP_DIR not set. You must set CT_TOP_DIR to the top directory where crosstool is installed." yann@1: exit 1 yann@1: fi yann@1: yann@1: # Parse the common functions yann@1: . "${CT_TOP_DIR}/scripts/functions" yann@1: yann@1: CT_STAR_DATE=`CT_DoDate +%s%N` yann@1: CT_STAR_DATE_HUMAN=`CT_DoDate +%Y%m%d.%H%M%S` yann@1: yann@1: # Log to a temporary file until we have built our environment yann@1: CT_ACTUAL_LOG_FILE="`pwd`/$$.log" yann@1: yann@1: # CT_TOP_DIR should be an absolute path. yann@1: CT_TOP_DIR="`CT_MakeAbsolutePath \"${CT_TOP_DIR}\"`" yann@1: yann@1: # Parse the configuration file yann@1: CT_TestOrAbort "Configuration file not found. Please create one." -f "${CT_TOP_DIR}/.config" yann@1: . "${CT_TOP_DIR}/.config" yann@1: yann@1: # The progress bar indicator is asked for yann@1: if [ "${CT_LOG_PROGRESS_BAR}" = "y" ]; then yann@1: _CT_PROG_BAR() { yann@1: [ $((cpt/5)) -eq 0 ] && echo -en "/" yann@1: [ $((cpt/5)) -eq 1 ] && echo -en "-" yann@1: [ $((cpt/5)) -eq 2 ] && echo -en "\\" yann@1: [ $((cpt/5)) -eq 3 ] && echo -en "|" yann@1: echo -en "\r" yann@1: cpt=$(((cpt+1)%20)) yann@1: } yann@1: CT_PROG_BAR=_CT_PROG_BAR yann@1: export -f _CT_PROG_BAR yann@1: else yann@1: CT_PROG_BAR= yann@1: fi yann@1: yann@1: # Apply the color scheme if needed yann@1: if [ "${CT_LOG_USE_COLORS}" = "y" ]; then yann@1: CT_ERROR_COLOR="${_A_NOR}${_A_BRI}${_F_RED}" yann@1: CT_WARN_COLOR="${_A_NOR}${_A_BRI}${_F_YEL}" yann@1: CT_INFO_COLOR="${_A_NOR}${_A_BRI}${_F_GRN}" yann@1: CT_EXTRA_COLOR="${_A_NOR}${_A_DIM}${_F_GRN}" yann@1: CT_DEBUG_COLOR="${_A_NOR}${_A_DIM}${_F_WHI}" yann@1: CT_NORMAL_COLOR="${_A_NOR}" yann@1: else yann@1: CT_ERROR_COLOR= yann@1: CT_WARN_COLOR= yann@1: CT_INFO_COLOR= yann@1: CT_EXTRA_COLOR= yann@1: CT_DEBUG_COLOR= yann@1: CT_NORMAL_COLOR= yann@1: fi yann@1: yann@1: # Yes! We can do full logging from now on! yann@1: CT_DoLog INFO "Build started ${CT_STAR_DATE_HUMAN}" yann@1: yann@1: # Some sanity checks in the environment and needed tools yann@1: CT_DoLog INFO "Checking environment sanity" yann@1: yann@1: # Enable known ordering of files in directory listings: yann@1: CT_Test "Crosstool-NG might not work as expected with LANG=\"${LANG}\"" -n "${LANG}" yann@1: case "${LC_COLLATE},${LC_ALL}" in yann@1: # These four combinations are known to sort files in the correct order: yann@1: fr_FR*,) ;; yann@1: en_US*,) ;; yann@1: *,fr_FR*) ;; yann@1: *,en_US*) ;; yann@1: # Anything else is destined to be borked if not gracefuly handled: yann@1: *) CT_DoLog WARN "Either LC_COLLATE=\"${LC_COLLATE}\" or LC_ALL=\"${LC_ALL}\" is not supported." yann@1: export LC_ALL=`locale -a |egrep "^(fr_FR|en_US)" |head -n 1` yann@1: CT_TestOrAbort "Neither en_US* nor fr_FR* locales found on your system." -n "${LC_ALL}" yann@1: CT_DoLog WARN "Forcing to known working LC_ALL=\"${LC_ALL}\"." yann@1: ;; yann@1: esac yann@1: yann@1: # Other environment sanity checks yann@1: CT_TestAndAbort "Don't set LD_LIBRARY_PATH. It screws up the build." -n "${LD_LIBRARY_PATH}" yann@1: CT_TestAndAbort "Don't set CFLAGS. It screws up the build." -n "${CFLAGS}" yann@1: CT_TestAndAbort "Don't set CXXFLAGS. It screws up the build." -n "${CXXFLAGS}" yann@1: CT_Test "GREP_OPTIONS screws up the build. Resetting." -n "${GREP_OPTIONS}" yann@1: GREP_OPTIONS= yann@1: CT_HasOrAbort awk yann@1: CT_HasOrAbort sed yann@1: CT_HasOrAbort bison yann@1: CT_HasOrAbort flex yann@1: yann@1: CT_DoStep DEBUG "Dumping crosstool-NG configuration" yann@1: cat ${CT_TOP_DIR}/.config |egrep '^(# |)CT_' |CT_DoLog DEBUG yann@1: CT_EndStep yann@1: yann@1: CT_DoLog INFO "Building environment variables" yann@1: yann@1: # This should go in buildToolchain.sh, but we might need it because it could yann@1: # be used by the user in his/her paths definitions. yann@1: # Target triplet: CT_TARGET needs a little love: yann@1: case "${CT_ARCH_BE},${CT_ARCH_LE}" in yann@1: y,) target_endian_eb=eb; target_endian_el=;; yann@1: ,y) target_endian_eb=; target_endian_el=el;; yann@1: esac yann@1: case "${CT_ARCH}" in yann@1: arm) CT_TARGET="${CT_ARCH}${target_endian_eb}";; yann@1: mips) CT_TARGET="${CT_ARCH}${target_endian_el}";; yann@1: x86*) # Much love for this one :-( yann@1: # Ultimately, we should use config.sub to output the correct yann@1: # procesor name. Work for later... yann@1: arch="${CT_ARCH_ARCH}" yann@1: [ -z "${arch}" ] && arch="${CT_ARCH_TUNE}" yann@1: case "${CT_ARCH}" in yann@1: x86_64) CT_TARGET=x86_64;; yann@1: *) case "${arch}" in yann@1: "") CT_TARGET=i386;; yann@1: i386|i486|i586|i686) CT_TARGET="${arch}";; yann@1: winchip*) CT_TARGET=i486;; yann@1: pentium|pentium-mmx|c3*) CT_TARGET=i586;; yann@1: nocona|athlon*64|k8|athlon-fx|opteron) CT_TARGET=x86_64;; yann@1: pentiumpro|pentium*|athlon*) CT_TARGET=i686;; yann@1: *) CT_TARGET=i586;; yann@1: esac;; yann@1: esac;; yann@1: esac yann@1: case "${CT_TARGET_VENDOR}" in yann@1: "") CT_TARGET="${CT_TARGET}-unknown";; yann@1: *) CT_TARGET="${CT_TARGET}-${CT_TARGET_VENDOR}";; yann@1: esac yann@1: case "${CT_KERNEL}" in yann@1: linux*) CT_TARGET="${CT_TARGET}-linux";; yann@1: cygwin*) CT_TARGET="${CT_TARGET}-cygwin";; yann@1: esac yann@1: case "${CT_LIBC}" in yann@1: glibc) CT_TARGET="${CT_TARGET}-gnu";; yann@1: uClibc) CT_TARGET="${CT_TARGET}-uclibc";; yann@1: esac yann@46: case "${CT_ARCH_ABI}" in yann@46: eabi) CT_TARGET="${CT_TARGET}eabi";; yann@46: esac yann@1: CT_TARGET="`${CT_TOP_DIR}/tools/config.sub ${CT_TARGET}`" yann@1: yann@1: # Now, build up the variables from the user-configured options. yann@1: CT_KERNEL_FILE="${CT_KERNEL}-${CT_KERNEL_VERSION}" yann@1: CT_BINUTILS_FILE="binutils-${CT_BINUTILS_VERSION}" yann@1: if [ "${CT_CC_USE_CORE}" != "y" ]; then yann@1: CT_CC_CORE="${CT_CC}" yann@1: CT_CC_CORE_VERSION="${CT_CC_VERSION}" yann@1: CT_CC_CORE_EXTRA_CONFIG="${CT_CC_EXTRA_CONFIG}" yann@1: fi yann@1: CT_CC_CORE_FILE="${CT_CC_CORE}-${CT_CC_CORE_VERSION}" yann@1: CT_CC_FILE="${CT_CC}-${CT_CC_VERSION}" yann@1: CT_LIBC_FILE="${CT_LIBC}-${CT_LIBC_VERSION}" yann@1: [ "${CT_ARCH_FLOAT_SW_LIBFLOAT}" = "y" ] && CT_LIBFLOAT_FILE="libfloat-990616" yann@1: yann@1: # Kludge: If any of the configured options needs CT_TARGET or CT_TOP_DIR, yann@1: # then rescan the options file now: yann@1: . "${CT_TOP_DIR}/.config" yann@1: yann@1: # Determine build system if not set by the user yann@1: CT_Test "You did not specify the build system. Guessing." -z "${CT_BUILD}" yann@1: CT_BUILD="`${CT_TOP_DIR}/tools/config.sub \"${CT_BUILD:-\`${CT_TOP_DIR}/tools/config.guess\`}\"`" yann@1: yann@1: # Get rid of pre-existing installed toolchain and previous build directories. yann@1: # We need to do that _before_ we can safely log, because the log file will yann@1: # most probably be in the toolchain directory. yann@1: if [ -d "${CT_PREFIX_DIR}" ]; then yann@1: mv "${CT_PREFIX_DIR}" "${CT_PREFIX_DIR}.$$" yann@1: nohup rm -rf "${CT_PREFIX_DIR}.$$" >/dev/null 2>&1 & yann@1: fi yann@1: mkdir -p "${CT_PREFIX_DIR}" yann@1: if [ -d "${CT_BUILD_DIR}" ]; then yann@1: mv "${CT_BUILD_DIR}" "${CT_BUILD_DIR}.$$" yann@1: nohup rm -rf "${CT_BUILD_DIR}.$$" >/dev/null 2>&1 & yann@1: fi yann@1: mkdir -p "${CT_BUILD_DIR}" yann@1: yann@1: # Check now if we can write to the destination directory: yann@1: if [ -d "${CT_PREFIX_DIR}" ]; then yann@1: CT_TestAndAbort "Destination directory \"${CT_INSTALL_DIR}\" is not writeable" ! -w "${CT_PREFIX_DIR}" yann@1: else yann@1: mkdir -p "${CT_PREFIX_DIR}" || CT_Abort "Could not create destination directory \"${CT_PREFIX_DIR}\"" yann@1: fi yann@1: yann@1: # Redirect log to the actual log file now we can yann@1: # It's quite understandable that the log file will be installed in the yann@1: # install directory, so we must first ensure it exists and is writeable (above) yann@1: # before we can log there yann@1: t="${CT_ACTUAL_LOG_FILE}" yann@1: case "${CT_LOG_TO_FILE},${CT_LOG_FILE}" in yann@1: ,*) CT_ACTUAL_LOG_FILE=/dev/null yann@1: rm -f "${t}" yann@1: ;; yann@1: y,/*) mkdir -p "`dirname \"${CT_LOG_FILE}\"`" yann@1: CT_ACTUAL_LOG_FILE="${CT_LOG_FILE}" yann@1: mv "${t}" "${CT_ACTUAL_LOG_FILE}" yann@1: ;; yann@1: y,*) mkdir -p "`pwd`/`dirname \"${CT_LOG_FILE}\"`" yann@1: CT_ACTUAL_LOG_FILE="`pwd`/${CT_LOG_FILE}" yann@1: mv "${t}" "${CT_ACTUAL_LOG_FILE}" yann@1: ;; yann@1: esac yann@1: yann@1: # Some more sanity checks now that we have all paths set up yann@1: case "${CT_TARBALLS_DIR},${CT_SRC_DIR},${CT_BUILD_DIR},${CT_PREFIX_DIR},${CT_INSTALL_DIR}" in yann@1: *" "*) CT_Abort "Don't use spaces in paths, it breaks things.";; yann@1: esac yann@1: yann@1: # Note: we'll always install the core compiler in its own directory, so as to yann@1: # not mix the two builds: core and final. Anyway, its generic, wether we use yann@1: # a different compiler as core, or not. yann@1: CT_CC_CORE_PREFIX_DIR="${CT_BUILD_DIR}/${CT_CC}-core" yann@1: yann@1: # Good, now grab a bit of informations on the system we're being run, yann@1: # just in case something goes awok, and it's not our fault: yann@1: CT_SYS_HOSTNAME=`hostname -f 2>/dev/null || true` yann@1: # Hmmm. Some non-DHCP-enabled machines do not have an FQDN... Fall back to node name. yann@1: CT_SYS_HOSTNAME="${CT_SYS_HOSTNAME:-`uname -n`}" yann@1: CT_SYS_KERNEL=`uname -s` yann@1: CT_SYS_REVISION=`uname -r` yann@1: # MacOS X lacks '-o' : yann@1: CT_SYS_OS=`uname -o || echo Unkown` yann@1: CT_SYS_MACHINE=`uname -m` yann@1: CT_SYS_PROCESSOR=`uname -p` yann@1: CT_SYS_USER="`id -un`" yann@1: CT_SYS_DATE=`CT_DoDate +%Y%m%d.%H%M%S` yann@1: CT_SYS_GCC=`gcc -dumpversion` yann@1: CT_TOOLCHAIN_ID="crosstool-${CT_VERSION} build ${CT_SYS_DATE} by ${CT_SYS_USER}@${CT_SYS_HOSTNAME} for ${CT_TARGET}" yann@1: yann@1: # renice oursleves yann@1: renice ${CT_NICE} $$ |CT_DoLog DEBUG yann@1: yann@1: # Include sub-scripts instead of calling them: that way, we do not have to yann@1: # export any variable, nor re-parse the configuration and functions files. yann@1: . "${CT_TOP_DIR}/scripts/getExtractPatch.sh" yann@1: . "${CT_TOP_DIR}/scripts/buildToolchain.sh" yann@1: #. "${CT_TOP_DIR}/scripts/testToolchain.sh" yann@1: yann@1: if [ -n "${CT_TARGET_ALIAS}" ]; then yann@1: CT_DoLog EXTRA "Creating symlinks from \"${CT_TARGET}-*\" to \"${CT_TARGET_ALIAS}-*\"" yann@1: CT_Pushd "${CT_PREFIX_DIR}/bin" yann@1: for t in "${CT_TARGET}-"*; do yann@1: _t="`echo \"$t\" |sed -r -e 's/^'\"${CT_TARGET}\"'-/'\"${CT_TARGET_ALIAS}\"'-/;'`" yann@1: CT_DoLog DEBUG "Linking \"${_t}\" -> \"${t}\"" yann@1: ln -s "${t}" "${_t}" yann@1: done yann@1: CT_Popd yann@1: fi yann@1: yann@14: if [ "${CT_REMOVE_DOCS}" = "y" ]; then yann@14: CT_DoLog INFO "Removing installed documentation" yann@14: rm -rf "${CT_PREFIX_DIR}/"{man,info} yann@14: fi yann@14: yann@1: CT_STOP_DATE=`CT_DoDate +%s%N` yann@1: CT_STOP_DATE_HUMAN=`CT_DoDate +%Y%m%d.%H%M%S` yann@1: CT_DoLog INFO "Build completed at ${CT_STOP_DATE_HUMAN}" yann@1: elapsed=$((CT_STOP_DATE-CT_STAR_DATE)) yann@1: elapsed_min=$((elapsed/(60*1000*1000*1000))) yann@1: elapsed_sec=`printf "%02d" $(((elapsed%(60*1000*1000*1000))/(1000*1000*1000)))` yann@1: elapsed_csec=`printf "%02d" $(((elapsed%(1000*1000*1000))/(10*1000*1000)))` yann@1: CT_DoLog INFO "(elapsed: ${elapsed_min}:${elapsed_sec}.${elapsed_csec})" yann@1: yann@1: # Restore a 'normal' color setting yann@1: echo -en "${CT_NORMAL_COLOR}" yann@1: yann@1: trap - EXIT