From fc2f73fc083085b6daeae1d1cbe7b380aaff3783 Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Thu, 9 Mar 2017 19:07:21 -0800 Subject: When moving gcc libs, prefer the same directory as libc If libc ended up in a directory other than /lib, place GCC's libs in that directory as well. Signed-off-by: Alexey Neyman --- scripts/build/cc/100-gcc.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'scripts/build/cc') diff --git a/scripts/build/cc/100-gcc.sh b/scripts/build/cc/100-gcc.sh index 56517d38..6cdcb31c 100644 --- a/scripts/build/cc/100-gcc.sh +++ b/scripts/build/cc/100-gcc.sh @@ -790,7 +790,7 @@ do_gcc_for_build() { gcc_movelibs() { local multi_flags multi_dir multi_os_dir multi_root multi_index multi_count - local gcc_dir + local gcc_dir dst_dir for arg in "$@"; do eval "${arg// /\\ }" @@ -803,6 +803,15 @@ gcc_movelibs() { # GCC didn't install anything outside of sysroot return fi + # Depending on the selected libc, we may or may not have the ${multi_os_dir_gcc} + # created by libc installation. If we do, use it. If we don't, use ${multi_os_dir} + # to avoid creating an otherwise empty directory. + dst_dir="${multi_root}/lib/${multi_os_dir_gcc}" + if [ ! -d "${dst_dir}" ]; then + dst_dir="${multi_root}/lib/${multi_os_dir}" + fi + CT_SanitizeVarDir dst_dir gcc_dir + ls "${gcc_dir}" | while read f; do case "${f}" in *.ld) @@ -812,8 +821,8 @@ gcc_movelibs() { ;; esac if [ -f "${gcc_dir}/${f}" ]; then - CT_DoExecLog ALL mkdir -p "${multi_root}/lib/${multi_os_dir}" - CT_DoExecLog ALL mv "${gcc_dir}/${f}" "${multi_root}/lib/${multi_os_dir}/${f}" + CT_DoExecLog ALL mkdir -p "${dst_dir}" + CT_DoExecLog ALL mv "${gcc_dir}/${f}" "${dst_dir}/${f}" fi done } -- cgit v1.2.3 From 11b52ab6d7aef83f624dccc81e0b479c5155fe31 Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Sun, 12 Mar 2017 23:01:23 -0700 Subject: Create ld.so.conf Also a fix for CT_IterateMultilibs: it didn't pass multi_os_dir_gcc, so it only worked if the caller did *not* declare it as a local variable. Signed-off-by: Alexey Neyman --- scripts/build/cc/100-gcc.sh | 2 +- scripts/build/internals.sh | 31 ++++++++++++++++++++++++++++++- scripts/functions | 17 +++++++++-------- 3 files changed, 40 insertions(+), 10 deletions(-) (limited to 'scripts/build/cc') diff --git a/scripts/build/cc/100-gcc.sh b/scripts/build/cc/100-gcc.sh index 6cdcb31c..9802521d 100644 --- a/scripts/build/cc/100-gcc.sh +++ b/scripts/build/cc/100-gcc.sh @@ -789,7 +789,7 @@ do_gcc_for_build() { } gcc_movelibs() { - local multi_flags multi_dir multi_os_dir multi_root multi_index multi_count + local multi_flags multi_dir multi_os_dir multi_os_dir_gcc multi_root multi_index multi_count local gcc_dir dst_dir for arg in "$@"; do diff --git a/scripts/build/internals.sh b/scripts/build/internals.sh index 7d91d781..a1c9b555 100644 --- a/scripts/build/internals.sh +++ b/scripts/build/internals.sh @@ -1,5 +1,27 @@ # This file contains crosstool-NG internal steps +create_ldso_conf() +{ + local multi_dir multi_os_dir multi_os_dir_gcc multi_root multi_flags multi_index multi_count multi_target + local b d + + for arg in "$@"; do + eval "${arg// /\\ }" + done + + CT_DoExecLog ALL mkdir -p "${multi_root}/etc" + for b in /lib /usr/lib /usr/local/lib; do + d="${b}/${multi_os_dir}" + CT_SanitizeVarDir d + echo "${d}" >> "${multi_root}/etc/ld.so.conf" + if [ "${multi_os_dir}" != "${multi_os_dir_gcc}" ]; then + d="${b}/${multi_os_dir_gcc}" + CT_SanitizeVarDir d + echo "${d}" >> "${multi_root}/etc/ld.so.conf" + fi + done +} + # This step is called once all components were built, to remove # un-wanted files, to add tuple aliases, and to add the final # crosstool-NG-provided files. @@ -10,7 +32,14 @@ do_finish() { local gcc_version local exe_suffix - CT_DoStep INFO "Cleaning-up the toolchain's directory" + CT_DoStep INFO "Finalizing the toolchain's directory" + + if [ "${CT_SHARED_LIBS}" = "y" ]; then + # Create /etc/ld.so.conf + CT_mkdir_pushd "${CT_BUILD_DIR}/build-create-ldso" + CT_IterateMultilibs create_ldso_conf create-ldso + CT_Popd + fi if [ "${CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES}" = "y" ]; then case "$CT_HOST" in diff --git a/scripts/functions b/scripts/functions index 3ef7bf67..ab141d5d 100644 --- a/scripts/functions +++ b/scripts/functions @@ -1750,13 +1750,14 @@ CT_IterateMultilibs() { dir_postfix=_${multi_dir//\//_} dir_postfix=${dir_postfix%_.} CT_mkdir_pushd "${prefix}${dir_postfix}" - $func multi_dir="${multi_dir}" \ - multi_os_dir="${multi_os_dir}" \ - multi_flags="${multi_flags}" \ - multi_root="${multi_root}" \ - multi_target="${multi_target}" \ - multi_index="${multi_index}" \ - multi_count="${#multilibs[@]}" \ + $func multi_dir="${multi_dir}" \ + multi_os_dir="${multi_os_dir}" \ + multi_os_dir_gcc="${multi_os_dir_gcc}" \ + multi_flags="${multi_flags}" \ + multi_root="${multi_root}" \ + multi_target="${multi_target}" \ + multi_index="${multi_index}" \ + multi_count="${#multilibs[@]}" \ "$@" CT_Popd multi_index=$((multi_index+1)) @@ -1819,7 +1820,7 @@ CT_SymlinkToolsMultilib() # Helper (iterator) for CT_MultilibFixupLDSO CT__FixupLDSO() { - local multi_dir multi_os_dir multi_root multi_flags multi_index multi_count + local multi_dir multi_os_dir multi_root multi_flags multi_index multi_count multi_target local binary local ldso ldso_l ldso_f ldso_d ldso_u multilib_dir -- cgit v1.2.3 From 63b2a19de4b33f304b236850028b6c6f32ce51e2 Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Fri, 17 Mar 2017 00:33:52 -0700 Subject: Add an option to "demultilib" It turns out buildroot does not currently accept a toolchain where a dynamic linker does not reside in the multi-os-directory. Unfortunately this is how glibc installs itself on AArch64 without any extra tricks. So, provide an option to force everything into /lib or /usr/lib; patch to buildroot will be worked on separately. Signed-off-by: Alexey Neyman --- config/target.in | 23 ++++++++++++++++++ scripts/build/cc/100-gcc.sh | 58 +++++++++++++++++++++++++++++---------------- 2 files changed, 61 insertions(+), 20 deletions(-) (limited to 'scripts/build/cc') diff --git a/config/target.in b/config/target.in index a905b239..485c5876 100644 --- a/config/target.in +++ b/config/target.in @@ -51,6 +51,29 @@ config MULTILIB NOTE: The multilib feature in crosstool-NG is not well-tested. Use at your own risk, and report success and/or failure. +config DEMULTILIB + bool "Attempt to combine libraries into a single directory" + default y if !MULTILIB + depends on !MULTILIB || EXPERIMENTAL + help + Normally, Crosstool-NG installs the libraries into the directories + as the configure for these libraries determines appropriate. For + example, for AArch64 glibc wants to install the libraries into + /lib64 but the default dynamic linker path is /lib/ld-linux-aarch64.so.1 + (which is installed as a symlink to ../lib64/ld-VER.so). + + However, not all consumers of the toolchain can handle the libraries + residing in multiple directories. To appease them, crosstool-NG can + attempt to combine the libraries back into a single /lib directory and + create all other directories as symlinks to /lib. This requires all + the library names to be unique within each sysroot. + + Note that GCC may also use separate sysroots for different multilibs. + Hence it may make sense to enable this option even for multilib toolchains. + However, separate roots are rare (any other architecture aside from + SuperH using them?) and hence not well tested in crosstool-NG; therefore, + this option is experimental when MULTILIB is enabled. + #-------------------------------------- config ARCH_SUPPORTS_BOTH_MMU bool diff --git a/scripts/build/cc/100-gcc.sh b/scripts/build/cc/100-gcc.sh index 9802521d..e3ae7830 100644 --- a/scripts/build/cc/100-gcc.sh +++ b/scripts/build/cc/100-gcc.sh @@ -129,6 +129,40 @@ cc_gcc_classify_opt() { echo "unknown" } +evaluate_multilib_cflags() +{ + local multi_dir multi_os_dir multi_os_dir_gcc multi_root multi_flags multi_index multi_count + local mdir mdir_os dirtop + local f + + for arg in "$@"; do + eval "${arg// /\\ }" + done + + mdir="lib/${multi_dir}" + mdir_os="lib/${multi_os_dir_gcc}" + CT_SanitizeVarDir mdir mdir_os + CT_DoLog EXTRA " '${multi_flags}' --> ${mdir} (gcc) ${mdir_os} (os)" + for f in ${multi_flags}; do + eval ml_`cc_gcc_classify_opt ${f}`=seen + done + if [ "${CT_DEMULTILIB}" = "y" ]; then + case "${mdir_os}" in + lib/*) + ;; + *) + dirtop="${mdir_os%%/*}" + if [ ! -e "${multi_root}/${mdir_os}" ]; then + CT_DoExecLog ALL ln -sfv lib "${multi_root}/${mdir_os}" + fi + if [ ! -e "${multi_root}/usr/${mdir_os}" ]; then + CT_DoExecLog ALL ln -sfv lib "${multi_root}/usr/${mdir_os}" + fi + ;; + esac + fi +} + #------------------------------------------------------------------------------ # This function lists the multilibs configured in the compiler (even if multilib # is disabled - so that it lists the default GCC/OS directory, which may differ @@ -151,9 +185,11 @@ cc_gcc_classify_opt() { # work, but 'gcc -mabi=32 -mabi=n32' produces an internal error in ld. Thus we do # not supply target's CFLAGS in multilib builds - and after compiling pass-1 gcc, # attempt to determine which CFLAGS need to be filtered out. +# +# 3. If "demultilibing" is in effect, create top-level directories for any +# multilibs not in lib/ as symlinks to lib. cc_gcc_multilib_housekeeping() { local cc host - local flags osdir dir multilibs i f local multilib_defaults local suffix sysroot base lnk local ml_arch ml_abi ml_cpu ml_tune ml_fpu ml_float ml_endian ml_mode ml_unknown ml @@ -175,25 +211,7 @@ cc_gcc_multilib_housekeeping() { multilib_defaults=( $( cc_gcc_get_spec multilib_defaults "${cc}" | \ sed 's/\(^\|[[:space:]]\+\)\([^[:space:]]\)/ -\2/g' ) ) CT_DoLog EXTRA "gcc default flags: '${multilib_defaults}'" - - multilibs=( $( "${cc}" -print-multi-lib ) ) - if [ ${#multilibs[@]} -ne 0 ]; then - CT_DoLog EXTRA "gcc configured with these multilibs (including the default):" - for i in "${multilibs[@]}"; do - dir="lib/${i%%;*}" - flags="${i#*;}" - flags=${flags//@/ -} - 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 - done - else - CT_DoLog WARN "no multilib configuration: GCC unusable?" - fi + CT_IterateMultilibs evaluate_multilib_cflags evaluate_cflags # Filtering out some of the options provided in CT-NG config. Then *prepend* # them to CT_TARGET_CFLAGS, like scripts/crosstool-NG.sh does. Zero out -- cgit v1.2.3