Support multilib in sh/uClibc.

Signed-off-by: Alexey Neyman <stilor@att.net>
This commit is contained in:
Alexey Neyman
2016-04-11 13:59:16 -07:00
parent 258394c19f
commit 98e556d386
4 changed files with 213 additions and 217 deletions

View File

@ -1366,25 +1366,6 @@ CT_DoBuildTargetTuple() {
fi
}
# This function determines the target tuple for a given set of compiler
# flags, using either GCC's multiarch feature (if supported; if not,
# GCC prints nothing and exits with status 0), falling back to calling
# the architecture-specific functions.
CT_DoMultilibTarget() {
local target_var="$1"; shift
local -a multi_flags=( "$@" )
local gcc_multiarch
gcc_multiarch=$( "${CT_TARGET}-gcc" -print-multiarch "${multi_flags[@]}" )
if [ -n "${gcc_multiarch}" ]; then
eval "${target_var}=${gcc_multiarch}"
return
fi
# Fall back to arch-specific guesswork
CT_DoArchMultilibTarget "${target_var}" "${multi_flags[@]}"
}
# This function does pause the build until the user strikes "Return"
# Usage: CT_DoPause [optional_message]
CT_DoPause() {
@ -1529,9 +1510,9 @@ CT_DoLoadState(){
# This function sets a kconfig option to a specific value in a .config file
# Usage: CT_KconfigSetOption <option> <value> <file>
CT_KconfigSetOption() {
option="$1"
value="$2"
file="$3"
local option="$1"
local value="$2"
local file="$3"
${grep} -E -q "^${option}=.*" "${file}" && \
${sed} -i -r -e "s;^${option}=.*$;${option}=${value};" "${file}" || \
@ -1543,8 +1524,8 @@ CT_KconfigSetOption() {
# This function enables a kconfig option to '=y' in a .config file
# Usage: CT_KconfigEnableOption <option> <file>
CT_KconfigEnableOption() {
option="$1"
file="$2"
local option="$1"
local file="$2"
CT_KconfigSetOption "${option}" "y" "${file}"
}
@ -1552,8 +1533,8 @@ CT_KconfigEnableOption() {
# This function disables a kconfig option in a .config file
# Usage: CT_KconfigDisableOption <option> <file>
CT_KconfigDisableOption() {
option="${1}"
file="${2}"
local option="${1}"
local file="${2}"
${grep} -E -q "^# ${option} is not set$" "${file}" || \
${grep} -E -q "^${option}=.*$" "${file}" && \
@ -1565,11 +1546,125 @@ CT_KconfigDisableOption() {
# is set or commented out.
# Usage: CT_KconfigDeleteOption <option> <file>
CT_KconfigDeleteOption() {
option="${1}"
file="${2}"
local option="${1}"
local file="${2}"
${grep} -E -q "^# ${option} is not set$" "${file}" && \
${sed} -i -r -e "/^# ${option} is not set$/d" "${file}" || \
${grep} -E -q "^${option}=.*$" "${file}" && \
${sed} -i -r -e "/^${option}=.*$/d" "${file}" || true
}
# Multilib iterator. The caller should be in a directory where the directories
# will be created, one per multilib, and the specified command will be run in
# each of them. The following arguments will be passed to the invoked command:
# multi_flags CFLAGS for this multilib
# multi_dir GCC internal library location for the multilib
# multi_os_dir OS library location for the multilib
# multi_root Sysroot for this multilib
# multi_target Target tuple, either as reported by GCC or by our guesswork
# multi_count Total number of multilibs
# multi_index Index of the current multilib
# Any additional arguments passed to this function will be forwarded to the called
# function as well.
# Usage: CT_IterateMultilibs <function> <prefix> <additional-args...>
CT_IterateMultilibs() {
local func="${1}"
local prefix="${2}"
local -a multilibs
local multi_dir multi_os_dir multi_root multi_flags multi_index multi_target
local root_suffix
# Name used internally below
if [ "${prefix}" = "sysroot-check" ]; then
CT_Abort "Bad prefix used in CT_IterateMultilibs"
fi
# Drop mandatory arguments
shift 2
# 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) )
CT_DoExecLog ALL rm -rf "sysroot-check"
for multilib in "${multilibs[@]}"; do
# GCC makes the distinction between:
# multilib (-print-multi-lib or -print-multi-directory) and
# multilib-os (--print-multi-os-directory)
# as the gcc library and gcc sysroot library paths, respectively.
# For example, on x86_64:
# multilib: -m32=32 -m64=.
# multilib-os: -m32=../lib -m64=../lib64
# Moreover, while some multilibs can coexist in the same sysroot (e.g.
# on x86), some have a "sysroot suffix" to separate incompatible variants.
# Such sysroot suffixes combine with multilib-os directories, e.g.
# on sh4 with -m4a multilib, the search order in sysroot is (dropping some
# directories for brevity:
# <sysroot>/m4a/lib/m4a/
# <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-check${root_suffix}"
if [ -e "sysroot-check${root_suffix}/seen" ]; then
CT_DoExecLog ALL rm -f "sysroot-check${root_suffix}/unique"
else
CT_DoExecLog ALL touch "sysroot-check${root_suffix}/seen" \
"sysroot-check${root_suffix}/unique"
fi
done
# Now, actual iteration.
# This uses either GCC's multiarch feature (if supported; if not,
# GCC prints nothing and exits with status 0), falling back to calling
# the architecture-specific functions.
multi_index=1
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} )
multi_target=$( "${CT_TARGET}-gcc" -print-multiarch ${multi_flags} )
root_suffix="${multi_root#${CT_SYSROOT_DIR}}"
# If GCC did not report the target tuple (i.e. this configuration is not
# multiarch-capable), fall back to our guesswork.
if [ -z "${multi_target}" ]; then
multi_target="${CT_TARGET}"
CT_DoArchMultilibTarget multi_target ${multi_flags}
fi
# Avoid multi_os_dir if it's the only directory in this sysroot.
if [ -e "sysroot-check${root_suffix}/unique" ]; then
multi_os_dir=.
fi
CT_mkdir_pushd "${prefix}_${multi_dir//\//_}"
$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[@]}" \
"$@"
CT_Popd
multi_index=$((multi_index+1))
done
}