From 58b4c6d0a44d57b15d7857ecb27711a2224949e9 Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN\"" Date: Mon, 7 May 2007 09:04:02 +0000 Subject: Merge the save-sample branch to trunk: - reorder most of the environment setup, - geting, extracting and patching are now components' sub-actions, - save the current config as a sample to be used as a pre-configured target. diff --git a/Makefile b/Makefile index 9ca5dad..fa6e2da 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,11 @@ all: _ct_build HOST_CC = gcc -funsigned-char help:: - @echo 'Available make targets (*: default target):' + @echo 'Available make targets:' @echo include $(CT_TOP_DIR)/kconfig/Makefile +include $(CT_TOP_DIR)/samples/Makefile help:: @echo 'Build targets:' @@ -26,6 +27,9 @@ help:: include $(CT_TOP_DIR)/tools/Makefile +help:: + @echo 'Execute "make" or "make all" to build all targets marked with [*]' + .config: $(shell find $(CT_TOP_DIR)/config -type f -name '*.in') @make menuconfig @# Because exiting menuconfig without saving is not an error to menuconfig diff --git a/config/global.in b/config/global.in index a3416cf..1f9c98f 100644 --- a/config/global.in +++ b/config/global.in @@ -162,33 +162,28 @@ config REMOVE_DOCS Remove the installed documentation (man and info pages). Gains around 8MiB for a uClibc-based, C and C++ compiler. -comment "Downloading and extracting" +comment "Downloading" -config NO_DOWNLOAD +config FORCE_DOWNLOAD bool - prompt "Avoid downloads" + prompt "Force downloads" default n help - Avoid downloading anything. Bail out if a tarball is missing. + Force downloading tarballs, even if one already exists. + + Usefull if you suspect a tarball to be damaged. config ONLY_DOWNLOAD bool - prompt "Only download tarballs" + prompt "Stop after downloading tarballs" default n - depends on ! NO_DOWNLOAD help Only download the tarballs. Exit once it done. Usefull to pre-retrieve the tarballs before going off-line. -config FORCE_DOWNLOAD - bool - prompt "Force downloads" - default n - depends on ! NO_DOWNLOAD - help - Force downloading tarballs, even if one already exists. - Usefull if you suspect a tarball to be damaged. +comment "Extracting" + depends on ! ONLY_DOWNLOAD config FORCE_EXTRACT bool @@ -201,6 +196,16 @@ config FORCE_EXTRACT Usefull if you suspect a previous extract did not complete (eg. broken tarball), or you added a new set of patches for this component. +config ONLY_EXTRACT + bool + prompt "Stop after extracting tarballs" + depends on ! ONLY_DOWNLOAD + default n + help + Exit after unpacking and patching tarballs. + + Usefull to look at the code before doing the build itself. + comment "Logging" choice diff --git a/kconfig/Makefile b/kconfig/Makefile index 7167c6f..ca97748 100644 --- a/kconfig/Makefile +++ b/kconfig/Makefile @@ -25,24 +25,14 @@ config: $(obj)/conf oldconfig: $(obj)/conf @$< -s $(KCONFIG_TOP) -# Build a list of all available samples -SAMPLES = $(patsubst $(CT_TOP_DIR)/samples/%,%,$(filter-out %Makefile,$(wildcard $(CT_TOP_DIR)/samples/*))) -.PHONY: $(SAMPLES) -$(SAMPLES): - @cp "$(CT_TOP_DIR)/samples/$(@)/crosstool.config" "$(CT_TOP_DIR)/.config" - @$(MAKE) oldconfig - # Help text used by make help help:: @echo 'General purpose configuration targets:' @echo ' config - Update current config using a line-oriented program' @echo ' menuconfig - Update current config using a menu based program' @echo ' oldconfig - Update current config using a provided .config as base' - @echo - @echo 'Preconfigured targets:' - @for s in $(SAMPLES); do \ - echo " $${s}"; \ - done + @# saveconfig is listed here for homogeneity, but implemented in samples/Makefile + @echo ' saveconfig - Save current config as a preconfigured target' @echo '' # Cheesy build diff --git a/samples/Makefile b/samples/Makefile new file mode 100644 index 0000000..7c15b6e --- /dev/null +++ b/samples/Makefile @@ -0,0 +1,17 @@ +# Build a list of all available samples + +SAMPLES = $(patsubst $(CT_TOP_DIR)/samples/%,%,$(filter-out %Makefile,$(wildcard $(CT_TOP_DIR)/samples/*))) +.PHONY: $(SAMPLES) +$(SAMPLES): + @cp "$(CT_TOP_DIR)/samples/$(@)/crosstool.config" "$(CT_TOP_DIR)/.config" + @$(MAKE) oldconfig + +help:: + @echo 'Preconfigured targets:' + @for s in $(SAMPLES); do \ + echo " $${s}"; \ + done + @echo '' + +saveconfig: + @$(CT_TOP_DIR)/scripts/saveSample.sh diff --git a/scripts/build/binutils.sh b/scripts/build/binutils.sh index 26493c4..7a3497d 100644 --- a/scripts/build/binutils.sh +++ b/scripts/build/binutils.sh @@ -2,6 +2,19 @@ # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package +# Download binutils +do_binutils_get() { + CT_GetFile "${CT_BINUTILS_FILE}" \ + ftp://ftp.gnu.org/gnu/binutils \ + ftp://ftp.kernel.org/pub/linux/devel/binutils +} + +# Extract binutils +do_binutils_extract() { + CT_ExtractAndPatch "${CT_BINUTILS_FILE}" +} + +# Build binutils do_binutils() { mkdir -p "${CT_BUILD_DIR}/build-binutils" cd "${CT_BUILD_DIR}/build-binutils" diff --git a/scripts/build/cc_core_gcc.sh b/scripts/build/cc_core_gcc.sh index bcfd2dc..a21777c 100644 --- a/scripts/build/cc_core_gcc.sh +++ b/scripts/build/cc_core_gcc.sh @@ -2,6 +2,26 @@ # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package +# Download core gcc +do_cc_core_get() { + # Ah! gcc folks are kind of 'different': they store the tarballs in + # subdirectories of the same name! That's because gcc is such /crap/ that + # it is such /big/ that it needs being splitted for distribution! Sad. :-( + # Arrgghh! Some of those versions does not follow this convention: + # gcc-3.3.3 lives in releases/gcc-3.3.3, while gcc-2.95.* isn't in a + # subdirectory! You bastard! + CT_GetFile "${CT_CC_CORE_FILE}" \ + ftp://ftp.gnu.org/gnu/gcc/${CT_CC_CORE_FILE} \ + ftp://ftp.gnu.org/gnu/gcc/releases/${CT_CC_CORE_FILE} \ + ftp://ftp.gnu.org/gnu/gcc +} + +# Extract core gcc +do_cc_core_extract() { + CT_ExtractAndPatch "${CT_CC_CORE_FILE}" +} + +# Build core gcc do_cc_core() { mkdir -p "${CT_BUILD_DIR}/build-cc-core" cd "${CT_BUILD_DIR}/build-cc-core" diff --git a/scripts/build/cc_gcc.sh b/scripts/build/cc_gcc.sh index 2479e5e..b7d36ee 100644 --- a/scripts/build/cc_gcc.sh +++ b/scripts/build/cc_gcc.sh @@ -2,6 +2,26 @@ # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package +# Download final gcc +do_cc_get() { + # Ah! gcc folks are kind of 'different': they store the tarballs in + # subdirectories of the same name! That's because gcc is such /crap/ that + # it is such /big/ that it needs being splitted for distribution! Sad. :-( + # Arrgghh! Some of those versions does not follow this convention: + # gcc-3.3.3 lives in releases/gcc-3.3.3, while gcc-2.95.* isn't in a + # subdirectory! You bastard! + CT_GetFile "${CT_CC_FILE}" \ + ftp://ftp.gnu.org/gnu/gcc/${CT_CC_FILE} \ + ftp://ftp.gnu.org/gnu/gcc/releases/${CT_CC_FILE} \ + ftp://ftp.gnu.org/gnu/gcc +} + +# Extract final gcc +do_cc_extract() { + CT_ExtractAndPatch "${CT_CC_FILE}" +} + +# Build final gcc do_cc() { CT_DoStep INFO "Installing final compiler" diff --git a/scripts/build/kernel_linux.sh b/scripts/build/kernel_linux.sh index c6ff608..985cd86 100644 --- a/scripts/build/kernel_linux.sh +++ b/scripts/build/kernel_linux.sh @@ -2,6 +2,27 @@ # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package +# Download the kernel +do_kernel_get() { + if [ "${CT_KERNEL_LINUX_HEADERS_USE_CUSTOM_DIR}" != "y" ]; then + CT_GetFile "${CT_KERNEL_FILE}" \ + ftp://ftp.kernel.org/pub/linux/kernel/v2.6 \ + ftp://ftp.kernel.org/pub/linux/kernel/v2.4 \ + ftp://ftp.kernel.org/pub/linux/kernel/v2.2 \ + ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing \ + http://ep09.pld-linux.org/~mmazur/linux-libc-headers + fi + return 0 +} + +# Extract kernel +do_kernel_extract() { + if [ "${CT_KERNEL_LINUX_HEADERS_USE_CUSTOM_DIR}" != "y" ]; then + CT_ExtractAndPatch "${CT_KERNEL_FILE}" + fi + return 0 +} + # Check kernel configuration do_kernel_check_config() { CT_DoStep INFO "Checking kernel configuration" diff --git a/scripts/build/libc_glibc.sh b/scripts/build/libc_glibc.sh index 2fa9ac7..8b3a6d0 100644 --- a/scripts/build/libc_glibc.sh +++ b/scripts/build/libc_glibc.sh @@ -2,6 +2,33 @@ # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package +# Download glibc +do_libc_download() { + # Ah! Not all GNU folks seem stupid. All glibc releases are in the same + # directory. Good. Alas, there is no snapshot there. I'll deal with them + # later on... :-/ + CT_GetFile "${CT_LIBC_FILE}" ftp://ftp.gnu.org/gnu/glibc + + # C library addons + addons_list=`echo "${CT_LIBC_ADDONS}" |sed -r -e 's/,/ /g; s/ $//g;'` + for addon in ${addons_list}; do + CT_GetFile "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}" ftp://ftp.gnu.org/gnu/glibc + done + [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && CT_GetFile "${CT_LIBC}-ports-${CT_LIBC_VERSION}" ftp://ftp.gnu.org/gnu/glibc +} + +# Extract glibc +do_libc_extract() { + CT_ExtractAndPatch "${CT_LIBC_FILE}" + + # C library addons + addons_list=`echo "${CT_LIBC_ADDONS}" |sed -r -e 's/,/ /g; s/ $//g;'` + for addon in ${addons_list}; do + CT_ExtractAndPatch "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}" + done + [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && CT_ExtractAndPatch "${CT_LIBC}-ports-${CT_LIBC_VERSION}" +} + # There is nothing to do for glibc check config do_libc_check_config() { CT_DoStep INFO "Checking C library configuration" @@ -44,7 +71,8 @@ do_libc_headers() { --host="${CT_TARGET}" \ --prefix=/usr \ --with-headers="${CT_HEADERS_DIR}" \ - --without-cvs --disable-sanity-checks \ + --without-cvs \ + --disable-sanity-checks \ --enable-hacker-mode \ --enable-add-ons="" \ --without-nptl 2>&1 |CT_DoLog DEBUG @@ -142,7 +170,7 @@ do_libc() { CT_DoLog DEBUG "Extra config args passed: \"${extra_config}\"" # Add some default CC args - extra_cc_args= + extra_cc_args="${CT_CFLAGS_FOR_HOST}" case "${CT_LIBC_EXTRA_CC_ARGS}" in *-mbig-endian*) ;; *-mlittle-endian*) ;; diff --git a/scripts/build/libc_libfloat.sh b/scripts/build/libc_libfloat.sh index 3828a3f..d40070f 100644 --- a/scripts/build/libc_libfloat.sh +++ b/scripts/build/libc_libfloat.sh @@ -2,6 +2,34 @@ # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package +# Define libfloat functions depending on wether it is selected or not +if [ "${CT_ARCH_FLOAT_SW_LIBFLOAT}" = "y" ]; then + +# Download libfloat +do_libfloat_get() { + # Please note: because the file we download, and the file we store on the + # file system don't have the same name, CT_GetFile will always try to + # download the file over and over. + # To avoid this, we check that the file we want already exists in the + # tarball directory first. This is an ugly hack that overrides the standard + # CT_GetFile behavior... Sight... + lib_float_url="ftp://ftp.de.debian.org/debian/pool/main/libf/libfloat/" + ext=`CT_GetFileExtension "${CT_LIBFLOAT_FILE}"` + if [ -z "${ext}" ]; then + CT_GetFile libfloat_990616.orig "${lib_float_url}" + ext=`CT_GetFileExtension "libfloat_990616.orig"` + # Hack: remove the .orig extension, and change _ to - + mv -v "${CT_TARBALLS_DIR}/libfloat_990616.orig${ext}" \ + "${CT_TARBALLS_DIR}/libfloat-990616${ext}" 2>&1 |CT_DoLog DEBUG + fi +} + +# Extract libfloat +do_libfloat_extract() { + [ "${CT_ARCH_FLOAT_SW_LIBFLOAT}" = "y" ] && CT_ExtractAndPatch "${CT_LIBFLOAT_FILE}" +} + +# Build libfloat do_libfloat() { # Here we build and install libfloat for the target, so that the C library # builds OK with those versions of gcc that have severed softfloat support @@ -29,3 +57,17 @@ do_libfloat() { CT_EndStep } + +else # "${CT_ARCH_FLOAT_SW_LIBFLOAT}" != "y" + +do_libfloat_get() { + true +} +do_libfloat_extract() { + true +} +do_libfloat() { + true +} + +fi diff --git a/scripts/build/libc_uClibc.sh b/scripts/build/libc_uClibc.sh index 171736d..5b1504c 100644 --- a/scripts/build/libc_uClibc.sh +++ b/scripts/build/libc_uClibc.sh @@ -2,6 +2,25 @@ # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package +# Download uClibc +do_libc_get() { + libc_src="http://www.uclibc.org/downloads + http://www.uclibc.org/downloads/snapshots + http://www.uclibc.org/downloads/old-releases" + # For uClibc, we have almost every thing: releases, and snapshots + # for the last month or so. We'll have to deal with svn revisions + # later... + CT_GetFile "${CT_LIBC_FILE}" ${libc_src} + # uClibc locales + [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ] && CT_GetFile "uClibc-locale-030818" ${libc_src} +} + +# Extract uClibc +do_libc_extract() { + CT_ExtractAndPatch "${CT_LIBC_FILE}" + # uClibc locales + [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ] && CT_ExtractAndPatch "uClibc-locale-030818" +} # Check that uClibc has been previously configured do_libc_check_config() { diff --git a/scripts/buildToolchain.sh b/scripts/buildToolchain.sh deleted file mode 100644 index a1bb18a..0000000 --- a/scripts/buildToolchain.sh +++ /dev/null @@ -1,133 +0,0 @@ -# This scripts calls each component's build script. -# Copyright 2007 Yann E. MORIN -# Licensed under the GPL v2. See COPYING in the root of this package - -# Parse all build files to have the needed functions. -. "${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" - -# 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 - -# 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 - -# Ha. cygwin host have an .exe suffix (extension) for executables. -[ "${CT_KERNEL}" = "cygwin" ] && EXEEXT=".exe" || EXEEXT="" - -# 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 -tmp_target_CFLAGS= -[ -n "${CT_ARCH_CPU}" ] && tmp_target_CFLAGS="${tmp_target_CFLAGS} -mcpu=${CT_ARCH_CPU}" -[ -n "${CT_ARCH_TUNE}" ] && tmp_target_CFLAGS="${tmp_target_CFLAGS} -mtune=${CT_ARCH_TUNE}" -[ -n "${CT_ARCH_ARCH}" ] && tmp_target_CFLAGS="${tmp_target_CFLAGS} -march=${CT_ARCH_ARCH}" -[ -n "${CT_ARCH_FPU}" ] && tmp_target_CFLAGS="${tmp_target_CFLAGS} -mfpu=${CT_ARCH_FPU}" -# Override with user-specified CFLAGS -CT_TARGET_CFLAGS="${tmp_target_CFLAGS} ${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 - -# Now for the job by itself. -# Check the C library config ASAP, before the user gets bored, and is -# gone having his/her coffee -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 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}-*\"" diff --git a/scripts/functions b/scripts/functions index f7d0879..5307268 100644 --- a/scripts/functions +++ b/scripts/functions @@ -218,3 +218,234 @@ CT_MktempDir() { CT_DoYes() { yes "$1" || true } + +# Download an URL using wget +# Usage: CT_DoGetFileWget +CT_DoGetFileWget() { + # Need to return true because it is legitimate to not find the tarball at + # some of the provided URLs (think about snapshots, different layouts for + # different gcc versions, etc...) + # Some (very old!) FTP server might not support the passive mode, thus + # retry without + # With automated download as we are doing, it can be very dangerous to use + # -c to continue the downloads. It's far better to simply overwrite the + # destination file + wget -nc --progress=dot:binary --tries=3 --passive-ftp "$1" || wget -nc --progress=dot:binary --tries=3 "$1" || true +} + +# Download an URL using curl +# Usage: CT_DoGetFileCurl +CT_DoGetFileCurl() { + # Note: comments about wget method are also valid here + # Plus: no good progreess indicator is available with curl, + # so output is consigned to oblivion + curl --ftp-pasv -O --retry 3 "$1" >/dev/null || curl -O --retry 3 "$1" >/dev/null || true +} + +# Wrapper function to call one of curl or wget +# Usage: CT_DoGetFile +CT_DoGetFile() { + local _wget=`which wget` + local _curl=`which curl` + case "${_wget},${_curl}" in + ,) CT_DoError "Could find neither wget nor curl";; + ,*) CT_DoGetFileCurl "$1";; + *) CT_DoGetFileWget "$1";; + esac +} + +# Download the file from one of the URLs passed as argument +# Usage: CT_GetFile [ ...] +CT_GetFile() { + local got_it + local ext + local url + local file="$1" + shift + + # Do we already have it? + ext=`CT_GetFileExtension "${file}"` + if [ -n "${ext}" ]; then + if [ "${CT_FORCE_DOWNLOAD}" = "y" ]; then + rm -f "${CT_TARBALLS_DIR}/${file}${ext}" + else + return 0 + fi + fi + + CT_DoLog EXTRA "Retrieving \"${file}\"" + CT_Pushd "${CT_TARBALLS_DIR}" + # File not yet downloaded, try to get it + got_it=0 + if [ "${got_it}" != "y" ]; then + # We'd rather have a bzip2'ed tarball, then gzipped, and finally plain tar. + for ext in .tar.bz2 .tar.gz .tgz .tar; do + # Try all urls in turn + for url in "$@"; do + case "${url}" in + *) CT_DoLog EXTRA "Trying \"${url}/${file}${ext}\"" + CT_DoGetFile "${url}/${file}${ext}" 2>&1 |CT_DoLog DEBUG + ;; + esac + [ -f "${file}${ext}" ] && got_it=1 && break 2 || true + done + done + fi + CT_Popd + + CT_TestAndAbort "Could not download \"${file}\", and not present in \"${CT_TARBALLS_DIR}\"" ${got_it} -eq 0 +} + +# Get the file name extension of a component +# Usage: CT_GetFileExtension +# If found, echoes the extension to stdout +# If not found, echoes nothing on stdout. +CT_GetFileExtension() { + local ext + local file="$1" + local got_it=1 + + CT_Pushd "${CT_TARBALLS_DIR}" + for ext in .tar.gz .tar.bz2 .tgz .tar; do + if [ -f "${file}${ext}" ]; then + echo "${ext}" + got_it=0 + break + fi + done + CT_Popd + + return 0 +} + +# Extract a tarball and patch the resulting sources if necessary. +# Some tarballs need to be extracted in specific places. Eg.: glibc addons +# must be extracted in the glibc directory; uCLibc locales must be extracted +# in the extra/locale sub-directory of uClibc. +CT_ExtractAndPatch() { + local file="$1" + local base_file=`echo "${file}" |cut -d - -f 1` + local ver_file=`echo "${file}" |cut -d - -f 2-` + local official_patch_dir + local custom_patch_dir + local libc_addon + local ext=`CT_GetFileExtension "${file}"` + CT_TestAndAbort "\"${file}\" not found in \"${CT_TARBALLS_DIR}\"" -z "${ext}" + local full_file="${CT_TARBALLS_DIR}/${file}${ext}" + + CT_Pushd "${CT_SRC_DIR}" + + # Add-ons need a little love, really. + case "${file}" in + glibc-[a-z]*-*) + CT_TestAndAbort "Trying to extract the C-library addon/locales \"${file}\" when C-library not yet extracted" ! -d "${CT_LIBC_FILE}" + cd "${CT_LIBC_FILE}" + libc_addon=y + [ -f ".${file}.extracted" ] && return 0 + touch ".${file}.extracted" + ;; + uClibc-locale-*) + CT_TestAndAbort "Trying to extract the C-library addon/locales \"${file}\" when C-library not yet extracted" ! -d "${CT_LIBC_FILE}" + cd "${CT_LIBC_FILE}/extra/locale" + libc_addon=y + [ -f ".${file}.extracted" ] && return 0 + touch ".${file}.extracted" + ;; + esac + + # If the directory exists, then consider extraction and patching done + [ -d "${file}" ] && return 0 + + CT_DoLog EXTRA "Extracting \"${file}\"" + case "${ext}" in + .tar.bz2) tar xvjf "${full_file}" |CT_DoLog DEBUG;; + .tar.gz|.tgz) tar xvzf "${full_file}" |CT_DoLog DEBUG;; + .tar) tar xvf "${full_file}" |CT_DoLog DEBUG;; + *) CT_Abort "Don't know how to handle \"${file}\": unknown extension" ;; + esac + + # Snapshots might not have the version number in the extracted directory + # name. This is also the case for some (old) packages, such as libfloat. + # Overcome this issue by symlink'ing the directory. + if [ ! -d "${file}" -a "${libc_addon}" != "y" ]; then + case "${ext}" in + .tar.bz2) base=`tar tjf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;; + .tar.gz|.tgz) base=`tar tzf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;; + .tar) base=`tar tf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;; + esac + CT_TestOrAbort "There was a problem when extracting \"${file}\"" -d "${base}" -o "${base}" != "${file}" + ln -s "${base}" "${file}" + fi + + # Kludge: outside this function, we wouldn't know if we had just extracted + # a libc addon, or a plain package. Apply patches now. + CT_DoLog EXTRA "Patching \"${file}\"" + + # If libc addon, we're already in the correct place. + [ -z "${libc_addon}" ] && cd "${file}" + + [ "${CUSTOM_PATCH_ONLY}" = "y" ] || official_patch_dir="${CT_TOP_DIR}/patches/${base_file}/${ver_file}" + [ "${CT_CUSTOM_PATCH}" = "y" ] && custom_patch_dir="${CT_CUSTOM_PATCH_DIR}/${base_file}/${ver_file}" + for patch_dir in "${official_patch_dir}" "${custom_patch_dir}"; do + if [ -n "${patch_dir}" -a -d "${patch_dir}" ]; then + for p in "${patch_dir}"/*.patch; do + if [ -f "${p}" ]; then + CT_DoLog DEBUG "Applying patch \"${p}\"" + patch -g0 -F1 -p1 -f <"${p}" |CT_DoLog DEBUG + CT_TestAndAbort "Failed while applying patch file \"${p}\"" ${PIPESTATUS[0]} -ne 0 + fi + done + fi + done + + CT_Popd +} + +# Compute the target triplet from what is provided by the user +# Usage: CT_DoBuildTargetTriplet +# In fact this function takes the environment variables to build the target +# triplet. It is needed both by the normal build sequence, as well as the +# sample saving sequence. +CT_DoBuildTargetTriplet() { + 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}`" +} diff --git a/scripts/getExtractPatch.sh b/scripts/getExtractPatch.sh deleted file mode 100644 index a1e829d..0000000 --- a/scripts/getExtractPatch.sh +++ /dev/null @@ -1,334 +0,0 @@ -# This script will download tarballs, extract them and patch the source. -# Copyright 2007 Yann E. MORIN -# Licensed under the GPL v2. See COPYING in the root of this package - -# Download tarballs in sequence. Once we have everything, start extracting -# and patching the tarballs. - -#----------------------------------------------------------------------------- - -_wget=`which wget || true` -_curl=`which curl || true` -#_svn=`which svn ||true` -#_cvs=`which cvs || true` - -case "${_wget},${_curl}" in - ,) CT_Abort "Found neither curl nor wget. Please install one.";; - ,*) CT_DoLog DEBUG "Using curl to retrieve tarballs"; CT_DoGetFile=CT_DoGetFileCurl;; - *) CT_DoLog DEBUG "Using wget to retrieve tarballs"; CT_DoGetFile=CT_DoGetFileWget;; -esac - -CT_DoGetFileWget() { - # Need to return true because it is legitimate to not find the tarball at - # some of the provided URLs (think about snapshots, different layouts for - # different gcc versions, etc...) - # Some (very old!) FTP server might not support the passive mode, thus - # retry without - # With automated download as we are doing, it can be very dangerous to use - # -c to continue the downloads. It's far better to simply overwrite the - # destination file - wget -nc --progress=dot:binary --tries=3 --passive-ftp "$1" || wget -nc --progress=dot:binary --tries=3 "$1" || true -} - -CT_DoGetFileCurl() { - # Note: comments about wget method are also valid here - # Plus: no good progreess indicator is available with curl, - # so output is consigned to oblivion - curl --ftp-pasv -O --retry 3 "$1" >/dev/null || curl -O --retry 3 "$1" >/dev/null || true -} - -# For those wanting bleading edge, or to retrieve old uClibc snapshots -# Usage: CT_GetFileSVN basename url -#CT_DoGetFileSVN() { -# local basename="$1" -# local url="`echo \"$2\" |cut -d : -f 2-`" -# local tmp_dir -# -# CT_TestOrAbort "You don't have subversion" -n "${_svn}" -# CT_MktempDir tmp_dir -# CT_Pushd "${tmp_dir}" -# svn export --force "${url}" "${basename}" -# tar cfj "${CT_TARBALLS_DIR}/${basename}.tar.bz2" "${basename}" -# CT_Popd -# rm -rf "${tmp_dir}" -#} -# -#CT_DoGetFileCVS() { -# : -#} - -# Download the file from one of the URLs passed as argument -# Usage: CT_GetFile [ ...] -CT_GetFile() { - local got_it - local ext - local url - local file="$1" - shift - - # Do we already have it? - ext=`CT_GetFileExtension "${file}"` - if [ -n "${ext}" ]; then - if [ "${CT_FORCE_DOWNLOAD}" = "y" ]; then - rm -f "${CT_TARBALLS_DIR}/${file}${ext}" - else - return 0 - fi - fi - - CT_DoLog EXTRA "Retrieving \"${file}\"" - CT_Pushd "${CT_TARBALLS_DIR}" - # File not yet downloaded, try to get it - got_it=0 - if [ "${got_it}" != "y" ]; then - # We'd rather have a bzip2'ed tarball, then gzipped, and finally plain tar. - for ext in .tar.bz2 .tar.gz .tgz .tar; do - # Try all urls in turn - for url in "$@"; do - case "${url}" in -# svn://*) CT_DoGetFileSVN "${file}" ${url}";; -# cvs://*) CT_DoGetFileCVS "${file}" ${url}";; - *) CT_DoLog EXTRA "Trying \"${url}/${file}${ext}\"" - ${CT_DoGetFile} "${url}/${file}${ext}" 2>&1 |CT_DoLog DEBUG - ;; - esac - [ -f "${file}${ext}" ] && got_it=1 && break 2 || true - done - done - fi - CT_Popd - - CT_TestAndAbort "Could not download \"${file}\", and not present in \"${CT_TARBALLS_DIR}\"" ${got_it} -eq 0 -} - -#----------------------------------------------------------------------------- - -# Extract a tarball and patch. -# Some tarballs need to be extracted in specific places. Eg.: glibc addons -# must be extracted in the glibc directory; uCLibc locales must be extracted -# in the extra/locale sub-directory of uClibc. -CT_ExtractAndPatch() { - local file="$1" - local base_file=`echo "${file}" |cut -d - -f 1` - local ver_file=`echo "${file}" |cut -d - -f 2-` - local official_patch_dir - local custom_patch_dir - local libc_addon - local ext=`CT_GetFileExtension "${file}"` - CT_TestAndAbort "\"${file}\" not found in \"${CT_TARBALLS_DIR}\"" -z "${ext}" - local full_file="${CT_TARBALLS_DIR}/${file}${ext}" - - CT_Pushd "${CT_SRC_DIR}" - - # Add-ons need a little love, really. - case "${file}" in - glibc-[a-z]*-*) - CT_TestAndAbort "Trying to extract the C-library addon/locales \"${file}\" when C-library not yet extracted" ! -d "${CT_LIBC_FILE}" - cd "${CT_LIBC_FILE}" - libc_addon=y - [ -f ".${file}.extracted" ] && return 0 - touch ".${file}.extracted" - ;; - uClibc-locale-*) - CT_TestAndAbort "Trying to extract the C-library addon/locales \"${file}\" when C-library not yet extracted" ! -d "${CT_LIBC_FILE}" - cd "${CT_LIBC_FILE}/extra/locale" - libc_addon=y - [ -f ".${file}.extracted" ] && return 0 - touch ".${file}.extracted" - ;; - esac - - # If the directory exists, then consider extraction and patching done - [ -d "${file}" ] && return 0 - - CT_DoLog EXTRA "Extracting \"${file}\"" - case "${ext}" in - .tar.bz2) tar xvjf "${full_file}" |CT_DoLog DEBUG;; - .tar.gz|.tgz) tar xvzf "${full_file}" |CT_DoLog DEBUG;; - .tar) tar xvf "${full_file}" |CT_DoLog DEBUG;; - *) CT_Abort "Don't know how to handle \"${file}\": unknown extension" ;; - esac - - # Snapshots might not have the version number in the extracted directory - # name. This is also the case for some (old) packages, such as libfloat. - # Overcome this issue by symlink'ing the directory. - if [ ! -d "${file}" -a "${libc_addon}" != "y" ]; then - case "${ext}" in - .tar.bz2) base=`tar tjf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;; - .tar.gz|.tgz) base=`tar tzf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;; - .tar) base=`tar tf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;; - esac - CT_TestOrAbort "There was a problem when extracting \"${file}\"" -d "${base}" -o "${base}" != "${file}" - ln -s "${base}" "${file}" - fi - - # Kludge: outside this function, we wouldn't know if we had just extracted - # a libc addon, or a plain package. Apply patches now. - CT_DoLog EXTRA "Patching \"${file}\"" - - # If libc addon, we're already in the correct place. - [ -z "${libc_addon}" ] && cd "${file}" - - [ "${CUSTOM_PATCH_ONLY}" = "y" ] || official_patch_dir="${CT_TOP_DIR}/patches/${base_file}/${ver_file}" - [ "${CT_CUSTOM_PATCH}" = "y" ] && custom_patch_dir="${CT_CUSTOM_PATCH_DIR}/${base_file}/${ver_file}" - for patch_dir in "${official_patch_dir}" "${custom_patch_dir}"; do - if [ -n "${patch_dir}" -a -d "${patch_dir}" ]; then - for p in "${patch_dir}"/*.patch; do - if [ -f "${p}" ]; then - CT_DoLog DEBUG "Applying patch \"${p}\"" - patch -g0 -F1 -p1 -f <"${p}" |CT_DoLog DEBUG - CT_TestAndAbort "Failed while applying patch file \"${p}\"" ${PIPESTATUS[0]} -ne 0 - fi - done - fi - done - - CT_Popd -} - -#----------------------------------------------------------------------------- - -# Get the file name extension of a component -# Usage: CT_GetFileExtension -# If found, echoes the extension to stdout -# If not found, echoes nothing on stdout. -CT_GetFileExtension() { - local ext - local file="$1" - local got_it=1 - - CT_Pushd "${CT_TARBALLS_DIR}" - for ext in .tar.gz .tar.bz2 .tgz .tar; do - if [ -f "${file}${ext}" ]; then - echo "${ext}" - got_it=0 - break - fi - done - CT_Popd - - return 0 -} - -#----------------------------------------------------------------------------- - -# Create needed directories, remove old ones -mkdir -p "${CT_TARBALLS_DIR}" -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_SRC_DIR}" - -# 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}\"`" - -# Prepare the addons list to be parsable: -addons_list="`echo \"${CT_LIBC_ADDONS_LIST}\" |sed -r -e 's/,/ /g; s/ $//g;'`" - -if [ "${CT_NO_DOWNLOAD}" != "y" ]; then - CT_DoStep INFO "Retrieving needed toolchain components' tarballs" - - # Kernel: for now, I don't care about cygwin. - if [ "${CT_KERNEL_LINUX_HEADERS_USE_CUSTOM_DIR}" != "y" ]; then - CT_GetFile "${CT_KERNEL_FILE}" \ - ftp://ftp.kernel.org/pub/linux/kernel/v2.6 \ - ftp://ftp.kernel.org/pub/linux/kernel/v2.4 \ - ftp://ftp.kernel.org/pub/linux/kernel/v2.2 \ - ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing \ - http://ep09.pld-linux.org/~mmazur/linux-libc-headers - fi - - # binutils - CT_GetFile "${CT_BINUTILS_FILE}" \ - ftp://ftp.gnu.org/gnu/binutils \ - ftp://ftp.kernel.org/pub/linux/devel/binutils - - # Core and final gcc - # Ah! gcc folks are kind of 'different': they store the tarballs in - # subdirectories of the same name! That's because gcc is such /crap/ that - # it is such /big/ that it needs being splitted for distribution! Sad. :-( - # Arrgghh! Some of those versions does not follow this convention: - # gcc-3.3.3 lives in releases/gcc-3.3.3, while gcc-2.95.* isn't in a - # subdirectory! You bastard! - CT_GetFile "${CT_CC_CORE_FILE}" \ - ftp://ftp.gnu.org/gnu/gcc/${CT_CC_CORE_FILE} \ - ftp://ftp.gnu.org/gnu/gcc/releases/${CT_CC_CORE_FILE} \ - ftp://ftp.gnu.org/gnu/gcc - CT_GetFile "${CT_CC_FILE}" \ - ftp://ftp.gnu.org/gnu/gcc/${CT_CC_FILE} \ - ftp://ftp.gnu.org/gnu/gcc/releases/${CT_CC_FILE} \ - ftp://ftp.gnu.org/gnu/gcc - - # C library - case "${CT_LIBC}" in - glibc) - # Ah! Not all GNU folks seem stupid. All glibc releases are in the same - # directory. Good. Alas, there is no snapshot there. I'll deal with them - # later on... :-/ - libc_src="ftp://ftp.gnu.org/gnu/glibc" - ;; - uClibc) - # For uClibc, we have almost every thing: releases, and snapshots - # for the last month or so. We'll have to deal with svn revisions - # later... - libc_src="http://www.uclibc.org/downloads - http://www.uclibc.org/downloads/snapshots - http://www.uclibc.org/downloads/old-releases" - ;; - esac - CT_GetFile "${CT_LIBC_FILE}" ${libc_src} - - # C library addons - addons_list=`echo "${CT_LIBC_ADDONS}" |sed -r -e 's/,/ /g; s/ $//g;'` - for addon in ${addons_list}; do - CT_GetFile "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}" ${libc_src} - done - [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && CT_GetFile "${CT_LIBC}-ports-${CT_LIBC_VERSION}" ${libc_src} - [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ] && CT_GetFile "uClibc-locale-030818" ${libc_src} - - # libfloat if asked for - if [ "${CT_ARCH_FLOAT_SW_LIBFLOAT}" = "y" ]; then - lib_float_url="ftp://ftp.de.debian.org/debian/pool/main/libf/libfloat/" - - # Please note: because the file we download, and the file we store on the - # file system don't have the same name, CT_GetFile will always try to - # download the file over and over. - # To avoid this, we check that the file we want already exists in the - # tarball directory first. This is an ugly hack that overrides the standard - # CT_GetFile behavior... Sight... - ext=`CT_GetFileExtension "${CT_LIBFLOAT_FILE}"` - if [ -z "${ext}" ]; then - CT_GetFile libfloat_990616.orig "${lib_float_url}" - ext=`CT_GetFileExtension "libfloat_990616.orig"` - # Hack: remove the .orig extension, and change _ to - - mv -v "${CT_TARBALLS_DIR}/libfloat_990616.orig${ext}" \ - "${CT_TARBALLS_DIR}/libfloat-990616${ext}" 2>&1 |CT_DoLog DEBUG - fi - fi - - CT_EndStep -fi # CT_NO_DOWNLOAD - -if [ "${CT_ONLY_DOWNLOAD}" != "y" ]; then - CT_DoStep INFO "Extracting and patching toolchain components" - - if [ "${CT_KERNEL_LINUX_HEADERS_USE_CUSTOM_DIR}" != "y" ]; then - CT_ExtractAndPatch "${CT_KERNEL_FILE}" - fi - CT_ExtractAndPatch "${CT_BINUTILS_FILE}" - CT_ExtractAndPatch "${CT_CC_CORE_FILE}" - CT_ExtractAndPatch "${CT_CC_FILE}" - CT_ExtractAndPatch "${CT_LIBC_FILE}" - for addon in ${addons_list}; do - CT_ExtractAndPatch "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}" - done - [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && CT_ExtractAndPatch "${CT_LIBC}-ports-${CT_LIBC_VERSION}" - [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ] && CT_ExtractAndPatch "uClibc-locale-030818" - - [ "${CT_ARCH_FLOAT_SW_LIBFLOAT}" = "y" ] && CT_ExtractAndPatch "${CT_LIBFLOAT_FILE}" - - CT_EndStep -fi diff --git a/scripts/saveSample.sh b/scripts/saveSample.sh new file mode 100755 index 0000000..1d01c66 --- /dev/null +++ b/scripts/saveSample.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# This script is responsible for saving the current configuration into a +# sample to be used later on as a pre-configured target. + +# What we need to save: +# - the .config file +# - the kernel .config file if specified +# - the uClibc .config file if uClibc selected + +. "${CT_TOP_DIR}/scripts/functions" + +# Log to a temporary file until we have built our environment +CT_ACTUAL_LOG_FILE="${CT_TOP_DIR}/$$.log" +CT_LOG_INFO=y +CT_LOG_LEVEL_MAX="INFO" + +# Parse the configuration file +CT_TestOrAbort "Configuration file not found. Please create one." -f "${CT_TOP_DIR}/.config" +. "${CT_TOP_DIR}/.config" + +# Override log level +unset CT_LOG_ERROR CT_LOG_WARN CT_LOG_EXTRA CT_LOG_DEBUG +CT_LOG_INFO=y +CT_LOG_LEVEL_MAX="INFO" + +# Target triplet: CT_TARGET needs a little love: +CT_DoBuildTargetTriplet + +# Create the sample directory +[ -d "${CT_TOP_DIR}/samples/${CT_TARGET}" ] || svn mkdir "${CT_TOP_DIR}/samples/${CT_TARGET}" >/dev/null 2>&1 + +# Save the crosstool-NG config file +cp "${CT_TOP_DIR}/.config" "${CT_TOP_DIR}/samples/${CT_TARGET}/crosstool.config" + +# Save the kernel .config file +if [ -n "${CT_KERNEL_LINUX_CONFIG_FILE}" ]; then + # We save the file, and then point the saved sample to this file + cp "${CT_KERNEL_LINUX_CONFIG_FILE}" "${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_KERNEL}-${CT_KERNEL_VERSION}.config" + svn add "${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_KERNEL}-${CT_KERNEL_VERSION}.config" >/dev/null 2>&1 + sed -r -i -e 's|^(CT_KERNEL_LINUX_CONFIG_FILE=).+$|\1"${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_KERNEL}-${CT_KERNEL_VERSION}.config"|;' \ + "${CT_TOP_DIR}/samples/${CT_TARGET}/crosstool.config" +else + # remove any dangling files + for f in "${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_KERNEL}-"*.config; do + if [ -f "${f}" ]; then svn rm --force "${f}" >/dev/null 2>&1; fi + done +fi + +# Save the uClibc .config file +if [ -n "${CT_LIBC_UCLIBC_CONFIG_FILE}" ]; then + # We save the file, and then point the saved sample to this file + cp "${CT_LIBC_UCLIBC_CONFIG_FILE}" "${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_LIBC}-${CT_LIBC_VERSION}.config" + svn add "${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_LIBC}-${CT_LIBC_VERSION}.config" >/dev/null 2>&1 + sed -r -i -e 's|^(CT_LIBC_UCLIBC_CONFIG_FILE=).+$|\1"${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_LIBC}-${CT_LIBC_VERSION}.config"|;' \ + "${CT_TOP_DIR}/samples/${CT_TARGET}/crosstool.config" +else + # remove any dangling files + for f in "${CT_TOP_DIR}/samples/${CT_TARGET}/${CT_LIBC}-"*.config; do + if [ -f "${f}" ]; then svn rm --force "${f}" >/dev/null 2>&1; fi + done +fi + +# We could svn add earlier, but it's better to +# add a frozen file than modifying it later +svn add "${CT_TOP_DIR}/samples/${CT_TARGET}/crosstool.config" >/dev/null 2>&1 + +svn stat "${CT_TOP_DIR}/samples/${CT_TARGET}" 2>/dev/null |CT_DoLog INFO + +rm -f "${CT_ACTUAL_LOG_FILE}" diff --git a/tools/Makefile b/tools/Makefile index 992792f..0886ac4 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -9,3 +9,4 @@ updatetools: help:: @echo ' updatetools - Update the config tools' + @echo '' -- cgit v0.10.2-6-g49f6