1 # Copyright 2019 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
4 # @ECLASS: usr-ldscript.eclass
6 # Toolchain Ninjas <toolchain@gentoo.org>
7 # @SUPPORTED_EAPIS: 4 5 6 7
8 # @BLURB: Defines the gen_usr_ldscript function.
10 if [[ -z ${_USR_LDSCRIPT_ECLASS} ]]; then
11 _USR_LDSCRIPT_ECLASS=1
15 *) die "EAPI=${EAPI} is not supported" ;;
18 inherit multilib toolchain-funcs
22 # @FUNCTION: gen_usr_ldscript
23 # @USAGE: [-a] <list of libs to create linker scripts for>
25 # This function generate linker scripts in /usr/lib for dynamic
26 # libs in /lib. This is to fix linking problems when you have
27 # the .so in /lib, and the .a in /usr/lib. What happens is that
28 # in some cases when linking dynamic, the .a in /usr/lib is used
29 # instead of the .so in /lib due to gcc/libtool tweaking ld's
30 # library search path. This causes many builds to fail.
31 # See bug #4411 for more info.
33 # Note that you should in general use the unversioned name of
34 # the library (libfoo.so), as ldconfig should usually update it
35 # correctly to point to the latest version of the library present.
37 local lib libdir=$(get_libdir) output_format="" auto=false suffix=$(get_libname)
39 tc-is-static-only && return
41 # We only care about stuffing / for the native ABI. #479448
42 if [[ $(type -t multilib_is_native_abi) == "function" ]] ; then
43 multilib_is_native_abi || return 0
46 # Eventually we'd like to get rid of this func completely #417451
47 case ${CTARGET:-${CHOST}} in
49 *-android*) return 0 ;;
50 *linux*|*-freebsd*|*-openbsd*|*-netbsd*)
51 use prefix && return 0
52 use split-usr || return 0
57 # Just make sure it exists
60 if [[ $1 == "-a" ]] ; then
66 # OUTPUT_FORMAT gives hints to the linker as to what binary format
67 # is referenced ... makes multilib saner
68 local flags=( ${CFLAGS} ${LDFLAGS} -Wl,--verbose )
69 if $(tc-getLD) --version | grep -q 'GNU gold' ; then
70 # If they're using gold, manually invoke the old bfd. #487696
71 local d="${T}/bfd-linker"
73 ln -sf $(which ${CHOST}-ld.bfd) "${d}"/ld
76 output_format=$($(tc-getCC) "${flags[@]}" 2>&1 | sed -n 's/^OUTPUT_FORMAT("\([^"]*\)",.*/\1/p')
77 [[ -n ${output_format} ]] && output_format="OUTPUT_FORMAT ( ${output_format} )"
82 lib="lib${lib}${suffix}"
84 # Ensure /lib/${lib} exists to avoid dangling scripts/symlinks.
85 # This especially is for AIX where $(get_libname) can return ".a",
86 # so /lib/${lib} might be moved to /usr/lib/${lib} (by accident).
87 [[ -r ${ED%/}/${libdir}/${lib} ]] || continue
88 #TODO: better die here?
91 case ${CTARGET:-${CHOST}} in
94 tlib=$(scanmacho -qF'%S#F' "${ED%/}"/usr/${libdir}/${lib})
96 tlib=$(scanmacho -qF'%S#F' "${ED%/}"/${libdir}/${lib})
98 [[ -z ${tlib} ]] && die "unable to read install_name from ${lib}"
102 mv "${ED%/}"/usr/${libdir}/${lib%${suffix}}.*${suffix#.} "${ED%/}"/${libdir}/ || die
103 # some install_names are funky: they encode a version
104 if [[ ${tlib} != ${lib%${suffix}}.*${suffix#.} ]] ; then
105 mv "${ED%/}"/usr/${libdir}/${tlib%${suffix}}.*${suffix#.} "${ED%/}"/${libdir}/ || die
107 rm -f "${ED%/}"/${libdir}/${lib}
110 # Mach-O files have an id, which is like a soname, it tells how
111 # another object linking against this lib should reference it.
112 # Since we moved the lib from usr/lib into lib this reference is
113 # wrong. Hence, we update it here. We don't configure with
114 # libdir=/lib because that messes up libtool files.
115 # Make sure we don't lose the specific version, so just modify the
116 # existing install_name
117 if [[ ! -w "${ED%/}/${libdir}/${tlib}" ]] ; then
118 chmod u+w "${ED%/}/${libdir}/${tlib}" # needed to write to it
122 -id "${EPREFIX}"/${libdir}/${tlib} \
123 "${ED%/}"/${libdir}/${tlib} || die "install_name_tool failed"
124 [[ -n ${nowrite} ]] && chmod u-w "${ED%/}/${libdir}/${tlib}"
125 # Now as we don't use GNU binutils and our linker doesn't
126 # understand linker scripts, just create a symlink.
127 pushd "${ED%/}/usr/${libdir}" > /dev/null
128 ln -snf "../../${libdir}/${tlib}" "${lib}"
133 tlib=$(scanelf -qF'%S#F' "${ED%/}"/usr/${libdir}/${lib})
134 [[ -z ${tlib} ]] && die "unable to read SONAME from ${lib}"
135 mv "${ED%/}"/usr/${libdir}/${lib}* "${ED%/}"/${libdir}/ || die
136 # some SONAMEs are funky: they encode a version before the .so
137 if [[ ${tlib} != ${lib}* ]] ; then
138 mv "${ED%/}"/usr/${libdir}/${tlib}* "${ED%/}"/${libdir}/ || die
140 rm -f "${ED%/}"/${libdir}/${lib}
144 cat > "${ED%/}/usr/${libdir}/${lib}" <<-END_LDSCRIPT
146 Since Gentoo has critical dynamic libraries in /lib, and the static versions
147 in /usr/lib, we need to have a "fake" dynamic lib in /usr/lib, otherwise we
148 run into linking problems. This "fake" dynamic lib is a linker script that
149 redirects the linker to the real lib. And yes, this works in the cross-
150 compiling scenario as the sysroot-ed linker will prepend the real path.
152 See bug https://bugs.gentoo.org/4411 for more info.
155 GROUP ( ${EPREFIX}/${libdir}/${tlib} )
159 fperms a+x "/usr/${libdir}/${lib}" || die "could not change perms on ${lib}"
163 fi # _USR_LDSCRIPT_ECLASS