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 <stilor@att.net>
This commit is contained in:
Alexey Neyman 2017-03-17 00:33:52 -07:00
parent 1ca65187f7
commit 63b2a19de4
2 changed files with 61 additions and 20 deletions

View File

@ -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

View File

@ -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