From 43c303c946c61469181d633cd5620cb92e44c329 Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Mon, 21 Mar 2016 11:18:53 -0700 Subject: libc/*.sh: handle combinations of multilib root/dir. Install startfiles for libc variants into the most specific combination (suffixed sysroot, if applicable + suffixed multi-os dir, if applicable). Install headers once in every suffixed sysroot (although it seems that GCC picks up headers from top-level sysroot, GCC manual claims that sysroot suffix affects headers search path). In uClibc, this requires a better sanitization of the directory: it creates symlinks from {sysroot}/usr/lib/{multi_os_dir} to {sysroot}/lib/{multi_os_dir} and to do so, it counts the number of path components in the libdir. This breaks if one of such components is `..' - symlinks contain an extra `../..' then. Since such sanitization had to be implemented anyway, use it in other places to print more sensible directory names. Also, fix the description of configure --host/--target per musl's configure help message (and its actual code). Signed-off-by: Alexey Neyman diff --git a/scripts/build/cc/100-gcc.sh b/scripts/build/cc/100-gcc.sh index 72e9dd0..db14728 100644 --- a/scripts/build/cc/100-gcc.sh +++ b/scripts/build/cc/100-gcc.sh @@ -192,11 +192,13 @@ cc_gcc_multilib_housekeeping() { if [ ${#multilibs[@]} -ne 0 ]; then CT_DoLog EXTRA "gcc configured with these multilibs (including the default):" for i in "${multilibs[@]}"; do - dir="${i%%;*}" + dir="lib/${i%%;*}" flags="${i#*;}" flags=${flags//@/ -} - osdir=$( "${cc}" -print-multi-os-directory ${flags} ) - CT_DoLog EXTRA " '${flags}' --> lib/${dir}/ (gcc) lib/${osdir} (os)" + flags=$( echo ${flags} ) + osdir="lib/"$( "${cc}" -print-multi-os-directory ${flags} ) + CT_SanitizeVarDir dir osdir + CT_DoLog EXTRA " '${flags}' --> ${dir} (gcc) ${osdir} (os)" for f in ${flags}; do eval ml_`cc_gcc_classify_opt ${f}`=seen done diff --git a/scripts/build/libc/glibc.sh b/scripts/build/libc/glibc.sh index c419603..c3926bf 100644 --- a/scripts/build/libc/glibc.sh +++ b/scripts/build/libc/glibc.sh @@ -70,14 +70,8 @@ do_libc_backend() { local libc_mode local -a multilibs local multilib - local multi_dir - local multi_flags - local multi_last + local multi_dir multi_os_dir multi_flags multi_last local target - local extra_dir - local target - local libc_headers libc_startfiles libc_full - local hdr local arg for arg in "$@"; do @@ -87,17 +81,13 @@ do_libc_backend() { case "${libc_mode}" in startfiles) CT_DoStep INFO "Installing C library headers & start files" - hdr=y - libc_startfiles=y - libc_full= ;; final) CT_DoStep INFO "Installing C library" - hdr= - libc_startfiles= - libc_full=y ;; - *) CT_Abort "Unsupported (or unset) libc_mode='${libc_mode}'";; + *) + CT_Abort "Unsupported (or unset) libc_mode='${libc_mode}'" + ;; esac # If gcc is not configured for multilib, it still prints @@ -130,37 +120,8 @@ do_libc_backend() { # /m4a/usr/lib/ multi_flags=$( echo "${multilib#*;}" | ${sed} -r -e 's/@/ -/g;' ) multi_dir="${multilib%%;*}" - if [ "${multi_dir}" != "." ]; then - CT_DoStep INFO "Building for multilib subdir='${multi_dir}'" - - extra_flags="${multi_flags}" - extra_dir="/${multi_dir}" - - # glibc install its files in ${extra_dir}/{usr/,}lib - # while gcc expects them in {,usr/}lib/${extra_dir}. - # Prepare some symlinks so glibc installs in fact in - # the proper place - # We do it in the start-files step, so it is not needed - # to do it in the final step, as the symlinks will - # already exist - if [ "${libc_mode}" = "startfiles" ]; then - CT_Pushd "${CT_SYSROOT_DIR}" - CT_DoExecLog ALL mkdir -p "lib/${multi_dir}" \ - "usr/lib/${multi_dir}" \ - "${multi_dir}" \ - "${multi_dir}/usr" - CT_DoExecLog ALL ln -sf "../lib/${multi_dir}" "${multi_dir}/lib" - CT_DoExecLog ALL ln -sf "../../usr/lib/${multi_dir}" "${multi_dir}/usr/lib" - CT_Popd - fi - libc_headers= - else - extra_dir= - extra_flags= - libc_headers="${hdr}" - fi - - CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-${libc_mode}${extra_dir//\//_}" + multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ${multi_flags} ) + multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ${multi_flags} ) target=$( CT_DoMultilibTarget "${CT_TARGET}" ${extra_flags} ) case "${target}" in @@ -186,18 +147,21 @@ do_libc_backend() { ;; esac - do_libc_backend_once extra_dir="${extra_dir}" \ - extra_flags="${extra_flags}" \ - libc_headers="${libc_headers}" \ - libc_startfiles="${libc_startfiles}" \ - libc_full="${libc_full}" \ - libc_target="${target}" \ - multi_last="${multi_last}" + CT_DoStep INFO "Building for multilib '${multi_flags}'" + + # Ensure sysroot (with suffix, if applicable) exists + CT_DoExecLog ALL mkdir -p "${multi_root}" + CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-${libc_mode}${multi_dir//\//_}" + do_libc_backend_once multi_dir="${multi_dir}" \ + multi_os_dir="${multi_os_dir}" \ + multi_flags="${multi_flags}" \ + multi_root="${multi_root}" \ + multi_last="${multi_last}" \ + libc_mode="${libc_mode}" \ + libc_target="${target}" CT_Popd - if [ "${multi_dir}" != "." ]; then - CT_EndStep - fi + CT_EndStep done @@ -206,23 +170,17 @@ do_libc_backend() { # This backend builds the C library once # Usage: do_libc_backend_once param=value [...] -# Parameter : Definition : Type : Default -# libc_headers : Build libc headers : bool : n -# libc_startfiles : Build libc start-files : bool : n -# libc_target : Build libc target triplet : string : ${CT_TARGET} -# libc_full : Build full libc : bool : n -# extra_flags : Extra CFLAGS to use (for multilib) : string : (empty) -# extra_dir : Extra subdir for multilib : string : (empty) +# Parameter : Definition : Type +# libc_mode : 'startfiles' or 'final' : string : (empty) +# libc_target : Build libc target triplet : string : (empty) +# multi_root : Installation root, chosen for multilib: string : (empty) +# multi_flags : Extra CFLAGS to use (for multilib) : string : (empty) +# multi_dir : Extra subdir for multilib (gcc) : string : (empty) +# multi_os_dir : Extra subdir for multilib (os) : string : (empty) # multi_last : The last multilib target : bool : n do_libc_backend_once() { - local libc_headers - local libc_startfiles - local libc_full - local extra_flags - local extra_dir - local extraos_dir - local lib_dir - local install_root + local multi_flags multi_dir multi_os_dir multi_root multi_last multi_root + local startfiles_dir local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}" local extra_cc_args local -a extra_config @@ -231,13 +189,32 @@ do_libc_backend_once() { local float_extra local endian_extra local libc_target="${CT_TARGET}" - local multi_last local arg for arg in "$@"; do eval "${arg// /\\ }" done + # Glibc seems to be smart enough to know about the cases that can coexist + # in the same root and installs them into proper multilib-os directory; all + # we need is to point to the right root. We do need to handle multilib-os + # here, though, for the first pass where we install crt*.o and a dummy + # libc.so; we therefore install it to the most specific location of + # //usr/lib/ where it is least likely to clash + # with other multilib variants. We then remove these temporary files at + # the beginning of the libc-final step and allow glibc to install them + # where it thinks is proper. + startfiles_dir="${multi_root}/usr/lib/${multi_os_dir}" + CT_SanitizeVarDir startfiles_dir + + if [ "${libc_mode}" = "final" ]; then + CT_DoLog EXTRA "Cleaning up start files" + CT_DoExecLog ALL rm -f "${startfiles_dir}/crt1.o" \ + "${startfiles_dir}/crti.o" \ + "${startfiles_dir}/crtn.o" \ + "${startfiles_dir}/libc.so" + fi + CT_DoLog EXTRA "Configuring C library" case "${CT_LIBC}" in @@ -253,7 +230,7 @@ do_libc_backend_once() { extra_config+=( --enable-obsolete-rpc ) # Add some default glibc config options if not given by user. - # We don't need to be conditional on wether the user did set different + # We don't need to be conditional on whether the user did set different # values, as they CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY is passed after # extra_config @@ -275,7 +252,7 @@ do_libc_backend_once() { *) extra_config+=("--disable-shared");; esac - float_extra="$( echo "${extra_flags}" \ + float_extra="$( echo "${multi_flags}" \ |${sed} -r -e '/^(.*[[:space:]])?-m(hard|soft)-float([[:space:]].*)?$/!d;' \ -e 's//\2/;' \ )" @@ -309,11 +286,11 @@ do_libc_backend_once() { # Extract the endianness options if any # This should cover all possible endianness options # in gcc, but it is prone to bit-rot... :-( - endian_extra="$( echo "${extra_flags}" \ + endian_extra="$( echo "${multi_flags}" \ |${sed} -r -e '/^(.*[[:space:]])?-(E[BL]|m((big|little)(-endian)?|e?[bl]))([[:space:]].*)?$/!d;' \ -e 's//\2/;' \ )" - # If extra_flags contained an endianness option, no need to add it again. Otherwise, + # If multi_flags contained an endianness option, no need to add it again. Otherwise, # add the option from the configuration. case "${endian_extra}" in EB|mbig-endian|mbig|meb|mb) @@ -333,8 +310,7 @@ do_libc_backend_once() { # Pre-seed the configparms file with values from the config option printf "%s\n" "${CT_LIBC_GLIBC_CONFIGPARMS}" > configparms - cross_cc=$(CT_Which "${CT_TARGET}-gcc") - extra_cc_args+=" ${extra_flags}" + extra_cc_args+=" ${multi_flags}" case "${CT_LIBC_ENABLE_FORTIFIED_BUILD}" in y) ;; @@ -355,24 +331,6 @@ do_libc_backend_once() { # or even after they get installed... echo "ac_cv_path_BASH_SHELL=/bin/bash" >>config.cache - - # GCC makes the distinction between: - # multilib (-print-multi-lib) and - # multilib-os (--print-multi-os-directory) - # as the gcc library and gcc sysroot library paths, respecitively. - # For example: - # multilib: -m32=32 -m64=. - # multilib-os: -m32=../lib -m64=../lib64 - if "${cross_cc}" -print-multi-os-directory ${extra_cc_args} > /dev/null 2>&1; then - lib_dir=/usr/lib/$("${cross_cc}" -print-multi-os-directory ${extra_cc_args}) - install_root="${CT_SYSROOT_DIR}" - else - # maintain the previous behaviour if -print-multi-os-directory doesn't work. - lib_dir=/usr/lib - install_root="${CT_SYSROOT_DIR}${extra_dir}" - fi - extraos_dir="${install_root}${lib_dir}" - # Configure with --prefix the way we want it on the target... # There are a whole lot of settings here. You'll probably want # to read up on what they all mean, and customize a bit, possibly by setting GLIBC_EXTRA_CONFIG_ARRAY @@ -383,14 +341,12 @@ do_libc_backend_once() { # Run explicitly through CONFIG_SHELL, or the build breaks badly (loop-of-death) # when the shell is not bash... Sigh... :-( - CT_DoLog DEBUG "Using gcc for target : '${cross_cc}'" CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'" CT_DoLog DEBUG "Extra config args passed : '${extra_config[*]}'" CT_DoLog DEBUG "Extra CC args passed : '${glibc_cflags}'" - CT_DoLog DEBUG "Extra flags (multilib) : '${extra_flags}'" - CT_DoLog DEBUG "Multilib os dir : '${extraos_dir}'" + CT_DoLog DEBUG "Extra flags (multilib) : '${multi_flags}'" + CT_DoLog DEBUG "Placing startfiles into : '${startfiles_dir}'" CT_DoLog DEBUG "Configuring with --host : '${libc_target}'" - CT_DoLog DEBUG "Configuring with --libdir: '${lib_dir}'" CT_DoExecLog CFG \ BUILD_CC="${CT_BUILD}-gcc" \ @@ -408,7 +364,6 @@ do_libc_backend_once() { --disable-profile \ --without-gd \ --with-headers="${CT_HEADERS_DIR}" \ - --libdir=${lib_dir} \ "${extra_config[@]}" \ "${CT_LIBC_GLIBC_EXTRA_CONFIG_ARRAY[@]}" @@ -439,13 +394,14 @@ do_libc_backend_once() { ;; esac - if [ "${libc_headers}" = "y" ]; then + if [ "${libc_mode}" = "startfiles" -a ! -r "${multi_root}/.libc_headers_installed" ]; then CT_DoLog EXTRA "Installing C library headers" + CT_DoExecLog ALL touch "${multi_root}/.libc_headers_installed" # use the 'install-headers' makefile target to install the # headers CT_DoExecLog ALL ${make} ${JOBSFLAGS} \ - install_root=${install_root} \ + install_root=${multi_root} \ install-bootstrap-headers=yes \ "${extra_make_args[@]}" \ install-headers @@ -486,35 +442,37 @@ do_libc_backend_once() { ;; esac fi - fi # libc_headers == y + elif [ "${libc_mode}" = "final" -a -r "${multi_root}/.libc_headers_installed" ]; then + CT_DoExecLog ALL rm -f "${multi_root}/.libc_headers_installed" + fi # installing headers - if [ "${libc_startfiles}" = "y" ]; then + if [ "${libc_mode}" = "startfiles" ]; then if [ "${CT_THREADS}" = "nptl" ]; then CT_DoLog EXTRA "Installing C library start files" # there are a few object files needed to link shared libraries, # which we build and install by hand - CT_DoExecLog ALL mkdir -p "${extraos_dir}" + CT_DoExecLog ALL mkdir -p "${startfiles_dir}" CT_DoExecLog ALL ${make} ${JOBSFLAGS} \ "${extra_make_args[@]}" \ csu/subdir_lib CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o \ - "${extraos_dir}" + "${startfiles_dir}" # Finally, 'libgcc_s.so' requires a 'libc.so' to link against. # However, since we will never actually execute its code, # it doesn't matter what it contains. So, treating '/dev/null' # as a C source file, we produce a dummy 'libc.so' in one step - CT_DoExecLog ALL "${cross_cc}" ${extra_flags} \ - -nostdlib \ - -nostartfiles \ - -shared \ - -x c /dev/null \ - -o "${extraos_dir}/libc.so" + CT_DoExecLog ALL "${CT_TARGET}-gcc" ${multi_flags} \ + -nostdlib \ + -nostartfiles \ + -shared \ + -x c /dev/null \ + -o "${startfiles_dir}/libc.so" fi # threads == nptl - fi # libc_headers == y + fi # libc_mode = startfiles - if [ "${libc_full}" = "y" ]; then + if [ "${libc_mode}" = "final" ]; then CT_DoLog EXTRA "Building C library" CT_DoExecLog ALL ${make} ${JOBSFLAGS} \ "${extra_make_args[@]}" \ @@ -523,7 +481,7 @@ do_libc_backend_once() { CT_DoLog EXTRA "Installing C library" CT_DoExecLog ALL ${make} ${JOBSFLAGS} \ "${extra_make_args[@]}" \ - install_root="${install_root}" \ + install_root="${multi_root}" \ install if [ "${CT_BUILD_MANUALS}" = "y" -a "${multi_last}" = "y" ]; then @@ -543,7 +501,7 @@ do_libc_backend_once() { if [ "${CT_LIBC_LOCALES}" = "y" -a "${multi_last}" = "y" ]; then do_libc_locales fi - fi # libc_full == y + fi # libc_mode = final } # Build up the addons list, separated with $1 diff --git a/scripts/build/libc/musl.sh b/scripts/build/libc/musl.sh index 2699d79..e0e9c63 100644 --- a/scripts/build/libc/musl.sh +++ b/scripts/build/libc/musl.sh @@ -46,6 +46,7 @@ do_libc_backend() { local -a extra_config local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}" local libc_headers libc_startfiles libc_full + local multi_os_dir multi_root multilib_dir for arg in "$@"; do eval "${arg// /\\ }" @@ -67,6 +68,12 @@ do_libc_backend() { *) CT_Abort "Unsupported (or unset) libc_mode='${libc_mode}'";; esac + multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ) + multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ) + multilib_dir="/usr/lib/${multi_os_dir}" + CT_SanitizeVarDir multilib_dir + CT_DoExecLog ALL mkdir -p "${multi_root}${multilib_dir}" + # From buildroot: # gcc constant folding bug with weak aliases workaround # See http://www.openwall.com/lists/musl/2014/05/15/1 @@ -89,37 +96,44 @@ do_libc_backend() { # NOTE: musl handles the build/host/target a little bit differently # then one would expect: # build : not used - # host : the machine building musl + # host : same as --target # target : the machine musl runs on - CT_DoExecLog CFG \ - CFLAGS="${extra_cflags[@]}" \ - CROSS_COMPILE="${CT_TARGET}-" \ - ${src_dir}/configure \ - --host="${CT_TARGET}" \ - --target="${CT_TARGET}" \ - --prefix="/usr" \ - --disable-gcc-wrapper \ + CT_DoExecLog CFG \ + CFLAGS="${extra_cflags[@]}" \ + CROSS_COMPILE="${CT_TARGET}-" \ + ${src_dir}/configure \ + --host="${CT_TARGET}" \ + --target="${CT_TARGET}" \ + --prefix="/usr" \ + --libdir="${multilib_dir}" \ + --disable-gcc-wrapper \ "${extra_config[@]}" if [ "${libc_headers}" = "y" ]; then CT_DoLog EXTRA "Installing C library headers" - CT_DoExecLog ALL ${make} DESTDIR="${CT_SYSROOT_DIR}" install-headers + CT_DoExecLog ALL ${make} DESTDIR="${multi_root}" install-headers fi if [ "${libc_startfiles}" = "y" ]; then CT_DoLog EXTRA "Building C library start files" - CT_DoExecLog ALL ${make} DESTDIR="${CT_SYSROOT_DIR}" \ + CT_DoExecLog ALL ${make} DESTDIR="${multi_root}" \ obj/crt/crt1.o obj/crt/crti.o obj/crt/crtn.o CT_DoLog EXTRA "Installing C library start files" - CT_DoExecLog ALL cp -av obj/crt/crt*.o "${CT_SYSROOT_DIR}/usr/lib" + CT_DoExecLog ALL cp -av obj/crt/crt*.o "${multi_root}${multilib_dir}" CT_DoExecLog ALL ${CT_TARGET}-gcc -nostdlib \ - -nostartfiles -shared -x c /dev/null -o "${CT_SYSROOT_DIR}/usr/lib/libc.so" + -nostartfiles -shared -x c /dev/null -o "${multi_root}${multilib_dir}/libc.so" fi if [ "${libc_full}" = "y" ]; then + CT_DoLog EXTRA "Cleaning up start files" + CT_DoExecLog ALL rm -f "${multi_root}${multilib_dir}/crt1.o" \ + "${multi_root}${multilib_dir}/crti.o" \ + "${multi_root}${multilib_dir}/crtn.o" \ + "${multi_root}${multilib_dir}/libc.so" + CT_DoLog EXTRA "Building C library" CT_DoExecLog ALL ${make} ${JOBSFLAGS} CT_DoLog EXTRA "Installing C library" - CT_DoExecLog ALL ${make} DESTDIR="${CT_SYSROOT_DIR}" install + CT_DoExecLog ALL ${make} DESTDIR="${multi_root}" install fi CT_EndStep diff --git a/scripts/build/libc/uClibc.sh b/scripts/build/libc/uClibc.sh index 422412c..7903a76 100644 --- a/scripts/build/libc/uClibc.sh +++ b/scripts/build/libc/uClibc.sh @@ -73,63 +73,62 @@ do_libc_check_config() { # Build and install headers and start files do_libc_start_files() { - local cross + local multi_os_dir multi_root startfiles_dir CT_DoStep INFO "Installing C library headers" # Simply copy files until uClibc has the ability to build out-of-tree CT_DoLog EXTRA "Copying sources to build dir" - CT_DoExecLog ALL cp -av "${CT_SRC_DIR}/${uclibc_name}-${CT_LIBC_VERSION}" \ + CT_DoExecLog ALL cp -a "${CT_SRC_DIR}/${uclibc_name}-${CT_LIBC_VERSION}" \ "${CT_BUILD_DIR}/build-libc-headers" cd "${CT_BUILD_DIR}/build-libc-headers" # Retrieve the config file CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/uClibc.config" .config - # uClibc uses the CROSS environment variable as a prefix to the - # compiler tools to use. Setting it to the empty string forces - # use of the native build host tools, which we need at this - # stage, as we don't have target tools yet. - # BUT! With NPTL, we need a cross-compiler (and we have it) - if [ "${CT_THREADS}" = "nptl" ]; then - cross="${CT_TARGET}-" - fi + multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ) + multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ) + startfiles_dir="${multi_root}/usr/lib/${multi_os_dir}" + CT_SanitizeVarDir startfiles_dir + CT_DoExecLog ALL mkdir -p "${startfiles_dir}" # Force the date of the pregen locale data, as the # newer ones that are referenced are not available CT_DoLog EXTRA "Applying configuration" CT_DoYes "" |CT_DoExecLog ALL \ - ${make} CROSS_COMPILE="${cross}" \ + ${make} CROSS_COMPILE="${CT_TARGET}-" \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ oldconfig CT_DoLog EXTRA "Building headers" CT_DoExecLog ALL \ ${make} ${CT_LIBC_UCLIBC_VERBOSITY} \ - CROSS_COMPILE="${cross}" \ + CROSS_COMPILE="${CT_TARGET}-" \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ headers CT_DoLog EXTRA "Installing headers" CT_DoExecLog ALL \ ${make} ${CT_LIBC_UCLIBC_VERBOSITY} \ - CROSS_COMPILE="${cross}" \ + CROSS_COMPILE="${CT_TARGET}-" \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ install_headers + # The check might look bogus, but it is the same condition as is used + # by GCC build script to enable/disable shared library support. if [ "${CT_THREADS}" = "nptl" ]; then CT_DoLog EXTRA "Building start files" CT_DoExecLog ALL \ ${make} ${CT_LIBC_UCLIBC_PARALLEL:+${JOBSFLAGS}} \ - CROSS_COMPILE="${cross}" \ + CROSS_COMPILE="${CT_TARGET}-" \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ STRIPTOOL=true \ ${CT_LIBC_UCLIBC_VERBOSITY} \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ @@ -139,7 +138,7 @@ do_libc_start_files() { # libm.so is needed for ppc, as libgcc is linked against libm.so # No problem to create it for other archs. CT_DoLog EXTRA "Building dummy shared libs" - CT_DoExecLog ALL "${cross}gcc" -nostdlib \ + CT_DoExecLog ALL "${CT_TARGET}-gcc" -nostdlib \ -nostartfiles \ -shared \ -x c /dev/null \ @@ -147,11 +146,11 @@ do_libc_start_files() { CT_DoLog EXTRA "Installing start files" CT_DoExecLog ALL ${install} -m 0644 lib/crt1.o lib/crti.o lib/crtn.o \ - "${CT_SYSROOT_DIR}/usr/lib" + "${startfiles_dir}" CT_DoLog EXTRA "Installing dummy shared libs" - CT_DoExecLog ALL ${install} -m 0755 libdummy.so "${CT_SYSROOT_DIR}/usr/lib/libc.so" - CT_DoExecLog ALL ${install} -m 0755 libdummy.so "${CT_SYSROOT_DIR}/usr/lib/libm.so" + CT_DoExecLog ALL ${install} -m 0755 libdummy.so "${startfiles_dir}/libc.so" + CT_DoExecLog ALL ${install} -m 0755 libdummy.so "${startfiles_dir}/libm.so" fi # CT_THREADS == nptl CT_EndStep @@ -159,6 +158,8 @@ do_libc_start_files() { # This function build and install the full uClibc do_libc() { + local multi_os_dir multi_root multilib_dir startfiles_dir + CT_DoStep INFO "Installing C library" # Simply copy files until uClibc has the ability to build out-of-tree @@ -170,6 +171,20 @@ do_libc() { # Retrieve the config file CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/uClibc.config" .config + multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ) + multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ) + startfiles_dir="${multi_root}/usr/lib/${multi_os_dir}" + + CT_DoLog EXTRA "Cleaning up startfiles" + CT_DoExecLog ALL rm -f "${startfiles_dir}/crt1.o" \ + "${startfiles_dir}/crti.o" \ + "${startfiles_dir}/crtn.o" \ + "${startfiles_dir}/libc.so" \ + "${startfiles_dir}/libm.so" + + multilib_dir="lib/${multi_os_dir}" + CT_SanitizeVarDir multilib_dir + # uClibc uses the CROSS environment variable as a prefix to the compiler # tools to use. The newly built tools should be in our path, so we need # only give the correct name for them. @@ -181,7 +196,7 @@ do_libc() { CT_DoYes "" |CT_DoExecLog CFG \ ${make} CROSS_COMPILE=${CT_TARGET}- \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ oldconfig @@ -193,7 +208,7 @@ do_libc() { ${make} -j1 \ CROSS_COMPILE=${CT_TARGET}- \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ STRIPTOOL=true \ ${CT_LIBC_UCLIBC_VERBOSITY} \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ @@ -202,7 +217,7 @@ do_libc() { ${make} ${CT_LIBC_UCLIBC_PARALLEL:+${JOBSFLAGS}} \ CROSS_COMPILE=${CT_TARGET}- \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ STRIPTOOL=true \ ${CT_LIBC_UCLIBC_VERBOSITY} \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ @@ -220,16 +235,17 @@ do_libc() { # We do _not_ want to strip anything for now, in case we specifically # asked for a debug toolchain, hence the STRIPTOOL= assignment # - # Note: JOBSFLAGS is not usefull for installation. + # Note: JOBSFLAGS is not useful for installation. # CT_DoLog EXTRA "Installing C library" CT_DoExecLog ALL \ ${make} CROSS_COMPILE=${CT_TARGET}- \ UCLIBC_EXTRA_CFLAGS="-pipe" \ - PREFIX="${CT_SYSROOT_DIR}/" \ + PREFIX="${multi_root}/" \ STRIPTOOL=true \ ${CT_LIBC_UCLIBC_VERBOSITY} \ LOCALE_DATA_FILENAME="${uclibc_local_tarball}.tgz" \ + MULTILIB_DIR="${multilib_dir}" \ install CT_EndStep diff --git a/scripts/crosstool-NG.sh.in b/scripts/crosstool-NG.sh.in index 9a4091a..b49c68e 100644 --- a/scripts/crosstool-NG.sh.in +++ b/scripts/crosstool-NG.sh.in @@ -298,7 +298,7 @@ if [ -z "${CT_RESTART}" ]; then CT_SYSROOT_DIR="${CT_PREFIX_DIR}/${CT_TARGET}/${CT_SYSROOT_REL_DIR}" CT_DEBUGROOT_DIR="${CT_PREFIX_DIR}/${CT_TARGET}/${CT_SYSROOT_DIR_PREFIX}/debug-root" CT_HEADERS_DIR="${CT_SYSROOT_DIR}/usr/include" - CT_SanitiseVarDir CT_SYSROOT_REL_DIR CT_SYSROOT_DIR CT_DEBUGROOT_DIR CT_HEADERS_DIR + CT_SanitizeVarDir CT_SYSROOT_REL_DIR CT_SYSROOT_DIR CT_DEBUGROOT_DIR CT_HEADERS_DIR 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}" @@ -312,7 +312,7 @@ if [ -z "${CT_RESTART}" ]; then CT_SYSROOT_DIR="${CT_PREFIX_DIR}/${CT_TARGET}" CT_DEBUGROOT_DIR="${CT_SYSROOT_DIR}" CT_HEADERS_DIR="${CT_SYSROOT_DIR}/include" - CT_SanitiseVarDir CT_SYSROOT_DIR CT_DEBUGROOT_DIR CT_HEADERS_DIR + CT_SanitizeVarDir CT_SYSROOT_DIR CT_DEBUGROOT_DIR CT_HEADERS_DIR # 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 diff --git a/scripts/functions b/scripts/functions index 557c028..2331557 100644 --- a/scripts/functions +++ b/scripts/functions @@ -1,6 +1,6 @@ # -*- mode: sh; tab-width: 4 -*- # vi: ts=4:sw=4:sts=4:et -# This file contains some usefull common functions +# This file contains some useful common functions # Copyright 2007 Yann E. MORIN # Licensed under the GPL v2. See COPYING in the root of this package @@ -308,21 +308,57 @@ CT_SanitizePath() { PATH="${new}" } -# Sanitise the directory name contained in the variable passed as argument: +# Sanitize the directory name contained in the variable passed as argument: # - remove duplicate / -# Usage: CT_SanitiseVarDir CT_PREFIX_DIR -CT_SanitiseVarDir() { +# - remove . (current dir) at the beginning, in the middle or at the end +# - resolve .. (parent dir) if there is a previous component +# - remove .. (parent dir) if at the root +# +# Usage: CT_SanitizeVarDir CT_PREFIX_DIR +CT_SanitizeVarDir() { local var local old_dir - local new_dir + local new_dir tmp for var in "$@"; do eval "old_dir=\"\${${var}}\"" - new_dir="$( printf "${old_dir}" \ - |${sed} -r -e 's:/+:/:g;' \ - )" + new_dir=$( echo "${old_dir}" | ${awk} ' +{ + isabs = $1 == "" # Started with a slash + trail = $NF == "" # Ending with a slash + ncomp = 0 # Components in a path so far + for (i = 1; i <= NF; i++) { + # Double-slash or current dir? Ignore + if ($i == "" || $i == ".") { + continue; + } + # .. pops the last component unless it is at the beginning + if ($i == ".." && ncomp != 0 && comps[ncomp] != "..") { + ncomp--; + continue; + } + comps[++ncomp] = $i; + } + seencomp = 0 + for (i = 1; i <= ncomp; i++) { + if (comps[i] == ".." && isabs) { + # /../ at the beginning is equivalent to / + continue; + } + printf "%s%s", isabs || i != 1 ? "/" : "", comps[i]; + seencomp = 1; + } + if (!seencomp && !isabs && !trail) { + # Eliminated all components, but no trailing slash - + # if the result is appened with /foo, must not become absolute + printf "."; + } + if ((!seencomp && isabs) || (seencomp && trail)) { + printf "/"; + } +}' FS=/ ) eval "${var}=\"${new_dir}\"" - CT_DoLog DEBUG "Sanitised '${var}': '${old_dir}' -> '${new_dir}'" + CT_DoLog DEBUG "Sanitized '${var}': '${old_dir}' -> '${new_dir}'" done } -- cgit v0.10.2-6-g49f6