mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2025-04-16 07:26:38 +00:00
Support multilib in sh/uClibc.
Signed-off-by: Alexey Neyman <stilor@att.net>
This commit is contained in:
parent
258394c19f
commit
98e556d386
@ -44,9 +44,39 @@ CT_DoArchUClibcConfig() {
|
||||
CT_KconfigDisableOption "CONFIG_SH3" "${cfg}"
|
||||
CT_KconfigDisableOption "CONFIG_SH4" "${cfg}"
|
||||
CT_KconfigDisableOption "CONFIG_SH4A" "${cfg}"
|
||||
case "${CT_ARCH_SH_VARIAN}" in
|
||||
case "${CT_ARCH_SH_VARIANT}" in
|
||||
sh3) CT_KconfigEnableOption "CONFIG_SH3" "${cfg}";;
|
||||
sh4) CT_KconfigEnableOption "CONFIG_SH4" "${cfg}";;
|
||||
sh4a) CT_KconfigEnableOption "CONFIG_SH4A" "${cfg}";;
|
||||
esac
|
||||
}
|
||||
|
||||
CT_DoArchUClibcCflags() {
|
||||
local cfg="${1}"
|
||||
local cflags="${2}"
|
||||
local f
|
||||
|
||||
for f in ${cflags}; do
|
||||
case "${f}" in
|
||||
-m3)
|
||||
CT_KconfigEnableOption "CONFIG_SH3" "${cfg}"
|
||||
;;
|
||||
-m4)
|
||||
CT_KconfigEnableOption "CONFIG_SH4" "${cfg}"
|
||||
CT_KconfigEnableOption "UCLIBC_HAS_FPU" "${cfg}"
|
||||
;;
|
||||
-m4-nofpu)
|
||||
CT_KconfigEnableOption "CONFIG_SH4" "${cfg}"
|
||||
CT_KconfigDisableOption "UCLIBC_HAS_FPU" "${cfg}"
|
||||
;;
|
||||
-m4a)
|
||||
CT_KconfigEnableOption "CONFIG_SH4A" "${cfg}"
|
||||
CT_KconfigEnableOption "UCLIBC_HAS_FPU" "${cfg}"
|
||||
;;
|
||||
-m4a-nofpu)
|
||||
CT_KconfigEnableOption "CONFIG_SH4A" "${cfg}"
|
||||
CT_KconfigDisableOption "UCLIBC_HAS_FPU" "${cfg}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
@ -64,11 +64,6 @@ do_libc_post_cc() {
|
||||
# libc_mode : 'startfiles' or 'final' : string : (none)
|
||||
do_libc_backend() {
|
||||
local libc_mode
|
||||
local -a multilibs
|
||||
local multilib
|
||||
local multi_dir multi_os_dir multi_root multi_flags multi_last
|
||||
local root_suffix
|
||||
local target
|
||||
local arg
|
||||
|
||||
for arg in "$@"; do
|
||||
@ -88,94 +83,7 @@ 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) )
|
||||
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${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}"
|
||||
CT_DoMultilibTarget target ${extra_flags}
|
||||
CT_DoArchGlibcAdjustTuple target
|
||||
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 "multilib_${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
|
||||
CT_EndStep
|
||||
|
||||
done
|
||||
|
||||
CT_IterateMultilibs do_libc_backend_once multilib libc_mode="${libc_mode}"
|
||||
CT_Popd
|
||||
CT_EndStep
|
||||
}
|
||||
@ -184,26 +92,28 @@ do_libc_backend() {
|
||||
# Usage: do_libc_backend_once param=value [...]
|
||||
# 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
|
||||
# multi_* : as defined in CT_IterateMultilibs : (varies) :
|
||||
do_libc_backend_once() {
|
||||
local multi_flags multi_dir multi_os_dir multi_root multi_last multi_root
|
||||
local multi_flags multi_dir multi_os_dir multi_root multi_index multi_count
|
||||
local startfiles_dir
|
||||
local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
|
||||
local -a extra_config
|
||||
local -a extra_make_args
|
||||
local glibc_cflags
|
||||
local libc_target="${CT_TARGET}"
|
||||
local arg opt
|
||||
|
||||
for arg in "$@"; do
|
||||
eval "${arg// /\\ }"
|
||||
done
|
||||
|
||||
CT_DoStep INFO "Building for multilib ${multi_index}/${multi_count}: '${multi_flags}'"
|
||||
|
||||
# Ensure sysroot (with suffix, if applicable) exists
|
||||
CT_DoExecLog ALL mkdir -p "${multi_root}"
|
||||
|
||||
# Adjust target tuple according GLIBC quirks
|
||||
CT_DoArchGlibcAdjustTuple multi_target
|
||||
|
||||
# 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
|
||||
@ -335,7 +245,7 @@ do_libc_backend_once() {
|
||||
CT_DoLog DEBUG "Extra config args passed : '${extra_config[*]}'"
|
||||
CT_DoLog DEBUG "Extra CFLAGS passed : '${glibc_cflags}'"
|
||||
CT_DoLog DEBUG "Placing startfiles into : '${startfiles_dir}'"
|
||||
CT_DoLog DEBUG "Configuring with --host : '${libc_target}'"
|
||||
CT_DoLog DEBUG "Configuring with --host : '${multi_target}'"
|
||||
|
||||
# CFLAGS are only applied when compiling .c files. .S files are compiled with ASFLAGS,
|
||||
# but they are not passed by configure. Thus, pass everything in CC instead.
|
||||
@ -348,7 +258,7 @@ do_libc_backend_once() {
|
||||
"${src_dir}/configure" \
|
||||
--prefix=/usr \
|
||||
--build=${CT_BUILD} \
|
||||
--host=${libc_target} \
|
||||
--host=${multi_target} \
|
||||
--cache-file="$(pwd)/config.cache" \
|
||||
--without-cvs \
|
||||
--disable-profile \
|
||||
@ -474,7 +384,7 @@ do_libc_backend_once() {
|
||||
install_root="${multi_root}" \
|
||||
install
|
||||
|
||||
if [ "${CT_BUILD_MANUALS}" = "y" -a "${multi_last}" = "y" ]; then
|
||||
if [ "${CT_BUILD_MANUALS}" = "y" -a "${multi_index}" = "${multi_count}" ]; then
|
||||
# We only need to build the manuals once. Only build them on the
|
||||
# last multilib target. If it's not multilib, it will happen on the
|
||||
# only target.
|
||||
@ -488,10 +398,12 @@ do_libc_backend_once() {
|
||||
${CT_PREFIX_DIR}/share/doc
|
||||
fi
|
||||
|
||||
if [ "${CT_LIBC_LOCALES}" = "y" -a "${multi_last}" = "y" ]; then
|
||||
if [ "${CT_LIBC_LOCALES}" = "y" -a "${multi_index}" = "${multi_count}" ]; then
|
||||
do_libc_locales
|
||||
fi
|
||||
fi # libc_mode = final
|
||||
|
||||
CT_EndStep
|
||||
}
|
||||
|
||||
# Build up the addons list, separated with $1
|
||||
|
@ -66,10 +66,7 @@ do_libc() {
|
||||
# Common backend for 1st and 2nd passes.
|
||||
do_libc_backend() {
|
||||
local libc_mode
|
||||
local -a multilibs
|
||||
local multilib
|
||||
local multi_dir multi_os_dir multi_flags
|
||||
local ldso ldso_f ldso_d multilib_dir
|
||||
local arg
|
||||
|
||||
for arg in "$@"; do
|
||||
eval "${arg// /\\ }"
|
||||
@ -82,43 +79,7 @@ do_libc_backend() {
|
||||
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
|
||||
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
|
||||
|
||||
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}" \
|
||||
multi_os_dir="${multi_os_dir}" \
|
||||
multi_flags="${multi_flags}" \
|
||||
multi_root="${multi_root}" \
|
||||
libc_mode="${libc_mode}"
|
||||
CT_EndStep
|
||||
done
|
||||
CT_IterateMultilibs do_libc_backend_once multilib libc_mode="${libc_mode}"
|
||||
|
||||
if [ "${libc_mode}" = "final" -a "${CT_SHARED_LIBS}" = "y" ]; then
|
||||
# uClibc and GCC disagree where the dynamic linker lives. uClibc always
|
||||
@ -127,42 +88,7 @@ do_libc_backend() {
|
||||
# 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.
|
||||
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 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.*}"
|
||||
ldso_f="${ldso##*/}"
|
||||
if [ -z "${ldso}" -o "${ldso_d}" = "${multilib_dir}" ]; then
|
||||
# GCC cannot produce shared executable, or the base directory
|
||||
# for ld.so is the same as the multi_os_directory
|
||||
continue
|
||||
fi
|
||||
|
||||
# If there is no such file in the expected ldso dir, create a symlink to
|
||||
# multilib_dir ld.so
|
||||
if [ ! -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
|
||||
done
|
||||
CT_IterateMultilibs do_libc_ldso_fixup ldso_fixup
|
||||
fi
|
||||
|
||||
CT_Popd
|
||||
@ -172,10 +98,10 @@ do_libc_backend() {
|
||||
# Common backend for 1st and 2nd passes, once per multilib.
|
||||
do_libc_backend_once() {
|
||||
local libc_mode
|
||||
local multi_dir multi_os_dir multi_root multilib_dir startfiles_dir
|
||||
local multi_dir multi_os_dir multi_root multi_flags multi_index multi_count
|
||||
local multilib_dir startfiles_dir
|
||||
local jflag=${CT_LIBC_UCLIBC_PARALLEL:+${JOBSFLAGS}}
|
||||
local -a make_args
|
||||
local build_dir
|
||||
local extra_cflags f cfg_cflags cf
|
||||
local hdr_install_subdir
|
||||
|
||||
@ -183,11 +109,11 @@ do_libc_backend_once() {
|
||||
eval "${arg// /\\ }"
|
||||
done
|
||||
|
||||
CT_DoStep INFO "Building for multilib ${multi_index}/${multi_count}: '${multi_flags}'"
|
||||
|
||||
# Simply copy files until uClibc has the ability to build out-of-tree
|
||||
CT_DoLog EXTRA "Copying sources to build dir"
|
||||
build_dir="multilib_${multi_dir//\//_}"
|
||||
CT_DoExecLog ALL cp -a "${CT_SRC_DIR}/${uclibc_name}-${CT_LIBC_VERSION}" "${build_dir}"
|
||||
CT_Pushd "${build_dir}"
|
||||
CT_DoExecLog ALL cp -aT "${CT_SRC_DIR}/${uclibc_name}-${CT_LIBC_VERSION}" .
|
||||
|
||||
multilib_dir="lib/${multi_os_dir}"
|
||||
startfiles_dir="${multi_root}/usr/${multilib_dir}"
|
||||
@ -326,7 +252,40 @@ do_libc_backend_once() {
|
||||
CT_DoExecLog ALL mv "${multi_root}/usr/include.new" "${multi_root}/usr/include/${hdr_install_subdir}"
|
||||
fi
|
||||
|
||||
CT_Popd
|
||||
CT_EndStep
|
||||
}
|
||||
|
||||
do_libc_ldso_fixup() {
|
||||
local multi_dir multi_os_dir multi_root multi_flags multi_index multi_count
|
||||
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}-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,\].*,,' )
|
||||
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
|
||||
}
|
||||
|
||||
# Initialises the .config file to sensible values
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user