summaryrefslogtreecommitdiff
path: root/scripts/build/libc
diff options
context:
space:
mode:
authorAlexey Neyman <stilor@att.net>2016-04-12 06:11:22 (GMT)
committerAlexey Neyman <stilor@att.net>2016-08-23 18:00:27 (GMT)
commit258394c19f7b3fd3700814d7b4de9336bb16e554 (patch)
tree2676fc4c1da1c7c27f37dcf1e903ee483d65c214 /scripts/build/libc
parent99dd2f6f60ff244f509d917dc00d080667a90f69 (diff)
Treat multiroots differently.
'ld' does not search for dependency libraries in multi_os_directory, so if there's both multi_os_directory and multi_root, and there is only one configuration in each multi_root, forgo the multi_os_directory suffix. Needed for sh4-multilib-linux-uclibc. Signed-off-by: Alexey Neyman <stilor@att.net>
Diffstat (limited to 'scripts/build/libc')
-rw-r--r--scripts/build/libc/glibc.sh56
-rw-r--r--scripts/build/libc/uClibc.sh44
2 files changed, 83 insertions, 17 deletions
diff --git a/scripts/build/libc/glibc.sh b/scripts/build/libc/glibc.sh
index dc9443c..8093e08 100644
--- a/scripts/build/libc/glibc.sh
+++ b/scripts/build/libc/glibc.sh
@@ -66,7 +66,8 @@ do_libc_backend() {
local libc_mode
local -a multilibs
local multilib
- local multi_dir multi_os_dir multi_flags multi_last
+ local multi_dir multi_os_dir multi_root multi_flags multi_last
+ local root_suffix
local target
local arg
@@ -86,18 +87,12 @@ do_libc_backend() {
;;
esac
+ CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-${libc_mode}"
+
# If gcc is not configured for multilib, it still prints
# a single line for the default settings
multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null) )
- last_multi=
for multilib in "${multilibs[@]}"; do
- last_multi=$(( ${#multilibs[@]} - 1 ))
- if [ "${multilib%%;*}" = "${multilibs[last_multi]%%;*}" ]; then
- # This is the last multilib build or multilib is '.'
- # (default target, not multilib)
- multi_last=y
- fi
-
# GCC makes the distinction between:
# multilib (-print-multi-lib or -print-multi-directory) and
# multilib-os (--print-multi-os-directory)
@@ -114,10 +109,50 @@ do_libc_backend() {
# <sysroot>/m4a/usr/lib/m4a/
# <sysroot>/m4a/lib/
# <sysroot>/m4a/usr/lib/
+ # The problem is that while GCC itself is aware of these subtleties, the
+ # binutils (notably, ld) it invokes under the hood are not. For example,
+ # if a shared library libfoo.so.1 requires libbar.so.1, ld will only search
+ # for libbar.so.1 in <sysroot>/m4a/usr/lib, but not in <sysroot>/m4a/usr/lib/m4a.
+ # In other words, 'gcc -lfoo -lbar' will work for both the default and -m4a
+ # cases, and 'gcc -lfoo' will work for the default, but not for -m4a. To
+ # address this, we first try to determine if the sysroot alone makes the
+ # configuration sufficiently unique. If there are no multilibs within the
+ # same suffixed sysroot, we can drop the multi_os_dir and both gcc and ld
+ # will work. If not, we'll supply both multi_root/multi_os_dir (which will
+ # likely break later, e.g. while building final GCC with C++ support). But,
+ # we've done all we can.
multi_flags=$( echo "${multilib#*;}" | ${sed} -r -e 's/@/ -/g;' )
multi_dir="${multilib%%;*}"
multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ${multi_flags} )
multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ${multi_flags} )
+ root_suffix="${multi_root#${CT_SYSROOT_DIR}}"
+ CT_DoExecLog ALL mkdir -p "sysroot${root_suffix}"
+ if [ -e "sysroot${root_suffix}/seen" ]; then
+ CT_DoExecLog ALL rm -f "sysroot${root_suffix}/unique"
+ else
+ CT_DoExecLog ALL touch "sysroot${root_suffix}/seen" "sysroot${root_suffix}/unique"
+ fi
+ done
+
+ last_multi=
+ for multilib in "${multilibs[@]}"; do
+ last_multi=$(( ${#multilibs[@]} - 1 ))
+ if [ "${multilib%%;*}" = "${multilibs[last_multi]%%;*}" ]; then
+ # This is the last multilib build or multilib is '.'
+ # (default target, not multilib)
+ multi_last=y
+ fi
+
+ multi_flags=$( echo "${multilib#*;}" | ${sed} -r -e 's/@/ -/g;' )
+ multi_dir="${multilib%%;*}"
+ multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ${multi_flags} )
+ multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ${multi_flags} )
+ root_suffix="${multi_root#${CT_SYSROOT_DIR}}"
+
+ # Avoid multi_os_dir if it's the only directory in this sysroot.
+ if [ -e "sysroot${root_suffix}/unique" ]; then
+ multi_os_dir=.
+ fi
# Adjust target tuple according to CFLAGS + any GLIBC quirks
target="${CT_TARGET}"
@@ -127,7 +162,7 @@ do_libc_backend() {
# 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//\//_}"
+ CT_mkdir_pushd "multilib_${multi_dir//\//_}"
do_libc_backend_once multi_dir="${multi_dir}" \
multi_os_dir="${multi_os_dir}" \
multi_flags="${multi_flags}" \
@@ -141,6 +176,7 @@ do_libc_backend() {
done
+ CT_Popd
CT_EndStep
}
diff --git a/scripts/build/libc/uClibc.sh b/scripts/build/libc/uClibc.sh
index 822d381..edde815 100644
--- a/scripts/build/libc/uClibc.sh
+++ b/scripts/build/libc/uClibc.sh
@@ -81,6 +81,8 @@ do_libc_backend() {
*) CT_Abort "Unsupported (or unset) libc_mode='${libc_mode}'";;
esac
+ CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-${libc_mode}"
+
# See glibc.sh for the explanation of this magic.
multilibs=( $("${CT_TARGET}-gcc" -print-multi-lib 2>/dev/null) )
for multilib in "${multilibs[@]}"; do
@@ -88,6 +90,26 @@ do_libc_backend() {
multi_dir="${multilib%%;*}"
multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ${multi_flags} )
multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ${multi_flags} )
+ root_suffix="${multi_root#${CT_SYSROOT_DIR}}"
+ CT_DoExecLog ALL mkdir -p "sysroot${root_suffix}"
+ if [ -e "sysroot${root_suffix}/seen" ]; then
+ CT_DoExecLog ALL rm -f "sysroot${root_suffix}/unique"
+ else
+ CT_DoExecLog ALL touch "sysroot${root_suffix}/seen" "sysroot${root_suffix}/unique"
+ fi
+ done
+
+ for multilib in "${multilibs[@]}"; do
+ multi_flags=$( echo "${multilib#*;}" | ${sed} -r -e 's/@/ -/g;' )
+ multi_dir="${multilib%%;*}"
+ multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ${multi_flags} )
+ multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ${multi_flags} )
+ root_suffix="${multi_root#${CT_SYSROOT_DIR}}"
+
+ # Avoid multi_os_dir if it's the only directory in this sysroot.
+ if [ -e "sysroot${root_suffix}/unique" ]; then
+ multi_os_dir=.
+ fi
CT_DoStep INFO "Building for multilib '${multi_flags}'"
do_libc_backend_once multi_dir="${multi_dir}" \
@@ -104,17 +126,23 @@ do_libc_backend() {
# and expects it in /lib for the other. So, create a symlink from lib
# to the actual location, but only if that will not override the actual
# file in /lib. Thus, need to do this after all the variants are built.
- CT_mkdir_pushd "${CT_BUILD_DIR}/build-libc-test-ldso"
- echo "int main(void) { return 0; }" > dummy.c
+ echo "int main(void) { return 0; }" > test-ldso.c
for multilib in "${multilibs[@]}"; do
multi_flags=$( echo "${multilib#*;}" | ${sed} -r -e 's/@/ -/g;' )
multi_os_dir=$( "${CT_TARGET}-gcc" -print-multi-os-directory ${multi_flags} )
multi_root=$( "${CT_TARGET}-gcc" -print-sysroot ${multi_flags} )
+ root_suffix="${multi_root#${CT_SYSROOT_DIR}}"
+
+ # Avoid multi_os_dir if it's the only directory in this sysroot.
+ if [ -e "sysroot${root_suffix}/unique" ]; then
+ multi_os_dir=.
+ fi
+
multilib_dir="/lib/${multi_os_dir}"
CT_SanitizeVarDir multilib_dir
- CT_DoExecLog ALL "${CT_TARGET}-gcc" -o dummy dummy.c ${multi_flags}
- ldso=$( ${CT_TARGET}-readelf -Wl dummy | \
+ CT_DoExecLog ALL "${CT_TARGET}-gcc" -o test-ldso test-ldso.c ${multi_flags}
+ ldso=$( ${CT_TARGET}-readelf -Wl test-ldso | \
grep 'Requesting program interpreter: ' | \
sed -e 's,.*: ,,' -e 's,\].*,,' )
ldso_d="${ldso%/ld*.so.*}"
@@ -135,9 +163,9 @@ do_libc_backend() {
"${multi_root}${ldso}"
fi
done
- CT_Popd
fi
+ CT_Popd
CT_EndStep
}
@@ -157,9 +185,9 @@ do_libc_backend_once() {
# Simply copy files until uClibc has the ability to build out-of-tree
CT_DoLog EXTRA "Copying sources to build dir"
- build_dir="${CT_BUILD_DIR}/build-libc-${libc_mode}${multi_dir//\//_}"
+ build_dir="multilib_${multi_dir//\//_}"
CT_DoExecLog ALL cp -a "${CT_SRC_DIR}/${uclibc_name}-${CT_LIBC_VERSION}" "${build_dir}"
- cd "${build_dir}"
+ CT_Pushd "${build_dir}"
multilib_dir="lib/${multi_os_dir}"
startfiles_dir="${multi_root}/usr/${multilib_dir}"
@@ -297,6 +325,8 @@ do_libc_backend_once() {
CT_DoExecLog ALL rm -rf "${multi_root}/usr/include/${hdr_install_subdir}"
CT_DoExecLog ALL mv "${multi_root}/usr/include.new" "${multi_root}/usr/include/${hdr_install_subdir}"
fi
+
+ CT_Popd
}
# Initialises the .config file to sensible values