summaryrefslogtreecommitdiff
path: root/eclass/usr-ldscript.eclass
diff options
context:
space:
mode:
authorV3n3RiX <venerix@redcorelinux.org>2019-07-19 22:05:27 +0100
committerV3n3RiX <venerix@redcorelinux.org>2019-07-19 22:05:27 +0100
commit121ed4eec41fbf03e1998d09eede1bf449da63b9 (patch)
treece9341d77d1507f67d4a3a1472da9011b5baa0a8 /eclass/usr-ldscript.eclass
parentdd762ff83c330186ee2ede002e08b2f780cddd51 (diff)
gentoo resync : 19.07.2019
Diffstat (limited to 'eclass/usr-ldscript.eclass')
-rw-r--r--eclass/usr-ldscript.eclass163
1 files changed, 163 insertions, 0 deletions
diff --git a/eclass/usr-ldscript.eclass b/eclass/usr-ldscript.eclass
new file mode 100644
index 000000000000..7e406267b644
--- /dev/null
+++ b/eclass/usr-ldscript.eclass
@@ -0,0 +1,163 @@
+# Copyright 2019 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: usr-ldscript.eclass
+# @MAINTAINER:
+# Toolchain Ninjas <toolchain@gentoo.org>
+# @SUPPORTED_EAPIS: 4 5 6 7
+# @BLURB: Defines the gen_usr_ldscript function.
+
+if [[ -z ${_USR_LDSCRIPT_ECLASS} ]]; then
+_USR_LDSCRIPT_ECLASS=1
+
+case ${EAPI:-0} in
+ 4|5|6|7) ;;
+ *) die "EAPI=${EAPI} is not supported" ;;
+esac
+
+inherit multilib toolchain-funcs
+
+IUSE="split-usr"
+
+# @FUNCTION: gen_usr_ldscript
+# @USAGE: [-a] <list of libs to create linker scripts for>
+# @DESCRIPTION:
+# This function generate linker scripts in /usr/lib for dynamic
+# libs in /lib. This is to fix linking problems when you have
+# the .so in /lib, and the .a in /usr/lib. What happens is that
+# in some cases when linking dynamic, the .a in /usr/lib is used
+# instead of the .so in /lib due to gcc/libtool tweaking ld's
+# library search path. This causes many builds to fail.
+# See bug #4411 for more info.
+#
+# Note that you should in general use the unversioned name of
+# the library (libfoo.so), as ldconfig should usually update it
+# correctly to point to the latest version of the library present.
+gen_usr_ldscript() {
+ local lib libdir=$(get_libdir) output_format="" auto=false suffix=$(get_libname)
+
+ tc-is-static-only && return
+
+ # We only care about stuffing / for the native ABI. #479448
+ if [[ $(type -t multilib_is_native_abi) == "function" ]] ; then
+ multilib_is_native_abi || return 0
+ fi
+
+ # Eventually we'd like to get rid of this func completely #417451
+ case ${CTARGET:-${CHOST}} in
+ *-darwin*) ;;
+ *-android*) return 0 ;;
+ *linux*|*-freebsd*|*-openbsd*|*-netbsd*)
+ use prefix && return 0
+ use split-usr || return 0
+ ;;
+ *) return 0 ;;
+ esac
+
+ # Just make sure it exists
+ dodir /usr/${libdir}
+
+ if [[ $1 == "-a" ]] ; then
+ auto=true
+ shift
+ dodir /${libdir}
+ fi
+
+ # OUTPUT_FORMAT gives hints to the linker as to what binary format
+ # is referenced ... makes multilib saner
+ local flags=( ${CFLAGS} ${LDFLAGS} -Wl,--verbose )
+ if $(tc-getLD) --version | grep -q 'GNU gold' ; then
+ # If they're using gold, manually invoke the old bfd. #487696
+ local d="${T}/bfd-linker"
+ mkdir -p "${d}"
+ ln -sf $(which ${CHOST}-ld.bfd) "${d}"/ld
+ flags+=( -B"${d}" )
+ fi
+ output_format=$($(tc-getCC) "${flags[@]}" 2>&1 | sed -n 's/^OUTPUT_FORMAT("\([^"]*\)",.*/\1/p')
+ [[ -n ${output_format} ]] && output_format="OUTPUT_FORMAT ( ${output_format} )"
+
+ for lib in "$@" ; do
+ local tlib
+ if ${auto} ; then
+ lib="lib${lib}${suffix}"
+ else
+ # Ensure /lib/${lib} exists to avoid dangling scripts/symlinks.
+ # This especially is for AIX where $(get_libname) can return ".a",
+ # so /lib/${lib} might be moved to /usr/lib/${lib} (by accident).
+ [[ -r ${ED%/}/${libdir}/${lib} ]] || continue
+ #TODO: better die here?
+ fi
+
+ case ${CTARGET:-${CHOST}} in
+ *-darwin*)
+ if ${auto} ; then
+ tlib=$(scanmacho -qF'%S#F' "${ED%/}"/usr/${libdir}/${lib})
+ else
+ tlib=$(scanmacho -qF'%S#F' "${ED%/}"/${libdir}/${lib})
+ fi
+ [[ -z ${tlib} ]] && die "unable to read install_name from ${lib}"
+ tlib=${tlib##*/}
+
+ if ${auto} ; then
+ mv "${ED%/}"/usr/${libdir}/${lib%${suffix}}.*${suffix#.} "${ED%/}"/${libdir}/ || die
+ # some install_names are funky: they encode a version
+ if [[ ${tlib} != ${lib%${suffix}}.*${suffix#.} ]] ; then
+ mv "${ED%/}"/usr/${libdir}/${tlib%${suffix}}.*${suffix#.} "${ED%/}"/${libdir}/ || die
+ fi
+ rm -f "${ED%/}"/${libdir}/${lib}
+ fi
+
+ # Mach-O files have an id, which is like a soname, it tells how
+ # another object linking against this lib should reference it.
+ # Since we moved the lib from usr/lib into lib this reference is
+ # wrong. Hence, we update it here. We don't configure with
+ # libdir=/lib because that messes up libtool files.
+ # Make sure we don't lose the specific version, so just modify the
+ # existing install_name
+ if [[ ! -w "${ED%/}/${libdir}/${tlib}" ]] ; then
+ chmod u+w "${ED%/}/${libdir}/${tlib}" # needed to write to it
+ local nowrite=yes
+ fi
+ install_name_tool \
+ -id "${EPREFIX}"/${libdir}/${tlib} \
+ "${ED%/}"/${libdir}/${tlib} || die "install_name_tool failed"
+ [[ -n ${nowrite} ]] && chmod u-w "${ED%/}/${libdir}/${tlib}"
+ # Now as we don't use GNU binutils and our linker doesn't
+ # understand linker scripts, just create a symlink.
+ pushd "${ED%/}/usr/${libdir}" > /dev/null
+ ln -snf "../../${libdir}/${tlib}" "${lib}"
+ popd > /dev/null
+ ;;
+ *)
+ if ${auto} ; then
+ tlib=$(scanelf -qF'%S#F' "${ED%/}"/usr/${libdir}/${lib})
+ [[ -z ${tlib} ]] && die "unable to read SONAME from ${lib}"
+ mv "${ED%/}"/usr/${libdir}/${lib}* "${ED%/}"/${libdir}/ || die
+ # some SONAMEs are funky: they encode a version before the .so
+ if [[ ${tlib} != ${lib}* ]] ; then
+ mv "${ED%/}"/usr/${libdir}/${tlib}* "${ED%/}"/${libdir}/ || die
+ fi
+ rm -f "${ED%/}"/${libdir}/${lib}
+ else
+ tlib=${lib}
+ fi
+ cat > "${ED%/}/usr/${libdir}/${lib}" <<-END_LDSCRIPT
+ /* GNU ld script
+ Since Gentoo has critical dynamic libraries in /lib, and the static versions
+ in /usr/lib, we need to have a "fake" dynamic lib in /usr/lib, otherwise we
+ run into linking problems. This "fake" dynamic lib is a linker script that
+ redirects the linker to the real lib. And yes, this works in the cross-
+ compiling scenario as the sysroot-ed linker will prepend the real path.
+
+ See bug https://bugs.gentoo.org/4411 for more info.
+ */
+ ${output_format}
+ GROUP ( ${EPREFIX}/${libdir}/${tlib} )
+ END_LDSCRIPT
+ ;;
+ esac
+ fperms a+x "/usr/${libdir}/${lib}" || die "could not change perms on ${lib}"
+ done
+}
+
+fi # _USR_LDSCRIPT_ECLASS