From 8600f3ce56f67a2a0d7b4a14eb9e8b1f0ec49dec Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Sun, 12 Mar 2017 16:56:19 -0700 Subject: Move tools alias creation to a common function ... and in addition to final toolchain aliasing, use it when configuring multilibs for glibc/musl. Note that uClibc does not need it, it is explicitly selecting the tools using CROSS_PREFIX. Signed-off-by: Alexey Neyman --- scripts/functions | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'scripts/functions') diff --git a/scripts/functions b/scripts/functions index 969e9bfb..8b12d8e7 100644 --- a/scripts/functions +++ b/scripts/functions @@ -1762,3 +1762,56 @@ CT_IterateMultilibs() { multi_index=$((multi_index+1)) done } + +# Create symbolic links in buildtools for binutils using a different +# target name. +# Usage: +# CT_SymlinkTools BIN-DIR SRC-DIR NEW-PREFIX SED-EXPR +CT_SymlinkTools() +{ + local bindir="$1" + local srcdir="$2" + local newpfx="$3" + local sedexpr="$4" + local dirpfx + local t _t + + # if bindir==srcdir, create symlinks just with the filename + if [ "${bindir}" != "${srcdir}" ]; then + dirpfx="${srcdir}/" + fi + + CT_Pushd "${srcdir}" + for t in "${CT_TARGET}-"*; do + if [ -n "${newpfx}" -a "${newpfx}" != "${CT_TARGET}" ]; then + _t="${newpfx}-${t#${CT_TARGET}-}" + CT_DoExecLog ALL ln -sfv "${dirpfx}${t}" "${bindir}/${_t}" + fi + if [ -n "${sedexpr}" ]; then + _t=$( echo "${t}" | sed -r -e "${sedexpr}" ) + if [ "${_t}" = "${t}" ]; then + CT_DoLog WARN "The sed expression '${sedexpr}' has no effect on '${t}'" + else + CT_DoExecLog ALL ln -sfv "${dirpfx}${t}" "${bindir}/${_t}" + fi + fi + done + CT_Popd +} + +# Create symbolic links for multilib iterator. Expects ${multi_target} +# variable to indicate the desired triplet for the tools. +CT_SymlinkToolsMultilib() +{ + # Make configure detect ${target}-tool binaries even if it is different + # from configured tuple. Only symlink to final tools if they're executable + # on build. + CT_SymlinkTools "${CT_BUILDTOOLS_PREFIX_DIR}/bin" \ + "${CT_BUILDTOOLS_PREFIX_DIR}/bin" "${multi_target}" + case "${CT_TOOLCHAIN_TYPE}" in + native|cross) + CT_SymlinkTools "${CT_BUILDTOOLS_PREFIX_DIR}/bin" \ + "${CT_PREFIX_DIR}/bin" "${multi_target}" + ;; + esac +} -- cgit v1.2.3 From b090e0f74d1ca0c0c45ec416c139f709a8e28f61 Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Sun, 12 Mar 2017 19:41:09 -0700 Subject: Fix up ld.so symlinks for musl Convert absolute targets to relative so that they are valid on the host, too. The procedure is very similar to uclibc, so it is moved into a common function. Signed-off-by: Alexey Neyman --- scripts/build/libc/musl.sh | 4 +- scripts/build/libc/uClibc.sh | 48 +----------------------- scripts/functions | 87 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 48 deletions(-) (limited to 'scripts/functions') diff --git a/scripts/build/libc/musl.sh b/scripts/build/libc/musl.sh index 3d6fe04f..5a53fd0a 100644 --- a/scripts/build/libc/musl.sh +++ b/scripts/build/libc/musl.sh @@ -29,7 +29,9 @@ do_libc() { } do_libc_post_cc() { - : + # MUSL creates dynamic linker symlink with absolute path - which works on the + # target but not on the host. We want our cross-ldd tool to work. + CT_MultilibFixupLDSO } do_libc_backend() { diff --git a/scripts/build/libc/uClibc.sh b/scripts/build/libc/uClibc.sh index fcabee84..9f1eb370 100644 --- a/scripts/build/libc/uClibc.sh +++ b/scripts/build/libc/uClibc.sh @@ -453,51 +453,5 @@ do_libc_post_cc() { # file in /lib. Thus, need to do this after all the variants are built. # Moreover, need to do this after the final compiler is built: on targets # that use elf2flt, the core compilers cannot find ld when running elf2flt. - CT_DoStep INFO "Checking dynamic linker symlinks" - CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-post_cc" - echo "int main(void) { return 0; }" > test-ldso.c - CT_IterateMultilibs do_libc_ldso_fixup ldso_fixup - CT_Popd - CT_EndStep -} - -do_libc_ldso_fixup() { - local multi_dir multi_os_dir multi_root multi_flags multi_index multi_count - local binary - local ldso ldso_f ldso_d multilib_dir - - for arg in "$@"; do - eval "${arg// /\\ }" - done - - CT_DoLog EXTRA "Checking dynamic linker for multilib '${multi_flags}'" - - multilib_dir="/lib/${multi_os_dir}" - CT_SanitizeVarDir multilib_dir - - CT_DoExecLog ALL "${CT_TARGET}-${CT_CC}" -o test-ldso ../test-ldso.c ${multi_flags} - if [ -r "test-ldso.gdb" ]; then - binary="test-ldso.gdb" - else - binary="test-ldso" - fi - if ${CT_TARGET}-readelf -Wl "${binary}" | grep -q 'Requesting program interpreter: '; then - ldso=$( ${CT_TARGET}-readelf -Wl "${binary}" | \ - grep 'Requesting program interpreter: ' | \ - sed -e 's,.*: ,,' -e 's,\].*,,' ) - fi - CT_DoLog DEBUG "Detected dynamic linker for multilib '${multi_flags}': '${ldso}'" - - ldso_d="${ldso%/ld*.so.*}" - ldso_f="${ldso##*/}" - # Create symlink if GCC produced an executable, dynamically linked, it was requesting - # a linker not in the current directory, and there is no such file in the expected - # ldso dir. - if [ -n "${ldso}" -a "${ldso_d}" != "${multilib_dir}" -a ! -r "${multi_root}${ldso}" ]; then - # Convert ldso_d to "how many levels we need to go up" and remove - # leading slash. - ldso_d=$( echo "${ldso_d#/}" | sed 's,[^/]\+,..,g' ) - CT_DoExecLog ALL ln -sf "${ldso_d}${multilib_dir}/${ldso_f}" \ - "${multi_root}${ldso}" - fi + CT_MultilibFixupLDSO } diff --git a/scripts/functions b/scripts/functions index 8b12d8e7..3ef7bf67 100644 --- a/scripts/functions +++ b/scripts/functions @@ -1815,3 +1815,90 @@ CT_SymlinkToolsMultilib() ;; esac } + +# Helper (iterator) for CT_MultilibFixupLDSO +CT__FixupLDSO() +{ + local multi_dir multi_os_dir multi_root multi_flags multi_index multi_count + local binary + local ldso ldso_l ldso_f ldso_d ldso_u multilib_dir + + for arg in "$@"; do + eval "${arg// /\\ }" + done + + CT_DoLog EXTRA "Checking dynamic linker for multilib '${multi_flags}'" + + multilib_dir="/lib/${multi_os_dir}" + CT_SanitizeVarDir multilib_dir + + CT_DoExecLog ALL "${CT_TARGET}-${CT_CC}" -o test-ldso ../test-ldso.c ${multi_flags} + if [ -r "test-ldso.gdb" ]; then + binary="test-ldso.gdb" + else + binary="test-ldso" + fi + if ${CT_TARGET}-readelf -Wl "${binary}" | grep -q 'Requesting program interpreter: '; then + ldso=$( ${CT_TARGET}-readelf -Wl "${binary}" | \ + grep 'Requesting program interpreter: ' | \ + sed -e 's,.*: ,,' -e 's,\].*,,' ) + fi + CT_DoLog DEBUG "Detected dynamic linker for multilib '${multi_flags}': '${ldso}'" + + # Create symlink if GCC produced a dynamically linked executable. + if [ -z "${ldso}" ]; then + return # Probably, we're building a static toolchain. + fi + + ldso_d="${ldso%/ld*.so.*}" + ldso_f="${ldso##*/}" + + # Convert ldso_d to "how many levels we need to go up" and remove + # leading slash. + ldso_u=$( echo "${ldso_d#/}" | sed 's,[^/]\+,..,g' ) + + # If the requested dynamic linker exists, but is a symlink - check that it is either + # relative (in which case, if it is readable, we trust libc to have created it properly) + # or otherwise, convert it from absolute (target) path to a relative path that works on + # both host & target. + if [ -L "${multi_root}${ldso}" ]; then + ldso_l=`readlink "${multi_root}${ldso}"` + case "${ldso_l}" in + /*) # Absolute, convert to relative + if [ -r "${multi_root}${ldso_l}" ]; then + CT_DoExecLog ALL ln -sfv "${ldso_u}${ldso_l}" "${multi_root}${ldso}" + else + CT_DoLog WARN "Compiler selects '${ldso}' as dynamic linker for '${multi_flags}'" + CT_DoLog WARN "but '${ldso}' is a symlink to '${ldso_l}' which is not valid on target." + fi + ;; + *) # Relative, must be readable + if [ ! -r "${multi_root}${ldso}" ]; then + CT_DoLog WARN "Compiler selects '${ldso}' as dynamic linker for '${multi_flags}'" + CT_DoLog WARN "but '${ldso}' is a symlink to '${ldso_l}' which is invalid relative symlink." + fi + ;; + esac + return + elif [ -r "${multi_root}${ldso}" ]; then + return # Not a symlink but readable - looks like libc installed a real executable. + fi + + # Is it requesting a linker not in the current directory? uClibc case. + if [ "${ldso_d}" != "${multilib_dir}" ]; then + CT_DoExecLog ALL ln -sfv "${ldso_u}${multilib_dir}/${ldso_f}" \ + "${multi_root}${ldso}" + fi +} + +# Go over multilib variants and check that the requested dynamic linker +# is present and resolves on both target and host. +CT_MultilibFixupLDSO() +{ + CT_DoStep INFO "Checking dynamic linker symlinks" + CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-check-ldso" + echo "int main(void) { return 0; }" > test-ldso.c + CT_IterateMultilibs CT__FixupLDSO ldso_fixup + CT_Popd + CT_EndStep +} -- 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/functions') 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