Build glibc32 for x86_64 as a glibc sub-package (RHEL-29228)

GCC for x86_64 includes 32-bit multilib support, requiring a 32-bit
glibc to be present when GCC is built.  That 32-bit glibc cannot come
from an i686 RPM because of limitations in Koji, so there is a hack
including a glibc32 "source" package that actually contains binaries
from an i686 build (and thus needs additional manual update steps).

Set up glibc.spec to build a glibc32 binary package directly when
building for x86_64, so avoiding the need for the separate glibc32
source package.  Do not generate ELF dependencies for glibc32 to avoid
accidentally having it chosen over glibc.686.

The list of files in the glibc32 package has been compared to that in
the previous package (the gnu/lib-names-32.h header is added, as its
previous omission appears to be a bug).  And the lists of files in the
other packages built from glibc.spec have also been compared before
and after this change, to make sure there aren't inappropriate changes
to those lists.

Resolves: RHEL-29228
Related: RHEL-25850

Fedora 40 commits: fc720e6194
                   1470fe1da7
This commit is contained in:
Arjun Shankar 2024-04-16 12:00:19 +02:00
parent 283b1ce2e8
commit 4df7ab7cf0
2 changed files with 141 additions and 5 deletions

View File

@ -171,7 +171,7 @@ Version: %{glibcversion}
# - It allows using the Release number without the %%dist tag in the dependency
# generator to make the generated requires interchangeable between Rawhide
# and ELN (.elnYY < .fcXX).
%global baserelease 4
%global baserelease 6
Release: %{baserelease}%{?dist}
# Licenses:
@ -1087,6 +1087,32 @@ that can be installed across architectures.
%dnl %%{without bootstrap}
%endif
##############################################################################
# glibc32 (only for use in building GCC, not shipped)
##############################################################################
%ifarch x86_64
%package -n glibc32
Summary: The GNU libc libraries (32-bit)
Conflicts: glibc(x86-32)
%dnl The gcc package does not use ELF dependencies to install glibc32:
%dnl BuildRequires: (glibc32 or glibc-devel(%{__isa_name}-32))
%dnl Not generating the ELF dependencies for glibc32 makes it less likely
%dnl that the package is selected by accident over glibc.i686.
AutoReqProv: no
%description -n glibc32
This package is only used for internal building of multilib aware
packages, like gcc, due to a technical limitation in the distribution
build environment. Any package which needs both 32-bit and 64-bit
runtimes at the same time must install glibc32 (marked as a 64-bit
package) to access the 32-bit development files during a 64-bit build.
This package is not supported or intended for use outside of the
distribution build enviroment. Regular users can install both 32-bit and
64-bit runtimes and development files without any problems.
%endif
##############################################################################
# Prepare for the build.
##############################################################################
@ -1251,12 +1277,10 @@ build()
--with-nonshared-cflags="$BuildFlagsNonshared" \
--enable-bind-now \
--build=%{target} \
${configure_host} \
--enable-stack-protector=strong \
--enable-systemtap \
${core_with_options} \
%ifarch x86_64
--enable-cet \
%endif
%ifarch %{ix86}
--disable-multi-arch \
%endif
@ -1289,6 +1313,17 @@ build()
popd
}
%ifarch x86_64
# Build for the glibc32 package.
GCC="$GCC -m32" GXX="$GXX -m32" BuildFlags="${BuildFlags/-m64/-m32}" configure_host="--host=i686-linux-gnu" build 32
%endif
configure_host=""
%ifarch x86_64
configure_host="--enable-cet"
%endif
# Default set of compiler options.
build
@ -1319,6 +1354,20 @@ for d in %{glibc_sysroot}%{_libdir} %{glibc_sysroot}/%{_lib}; do
done
%endif
%ifarch x86_64
# Install for the glibc32 package.
pushd build-%{target}-32
%make_build install_root=%{glibc_sysroot} install
popd
pushd %{glibc_sysroot}
rm -rf etc sbin var usr/bin usr/lib/gconv usr/libexec usr/sbin usr/share
rm -f lib/libnss_db* lib/libnss_hesiod* lib/libnsl* usr/lib/libnsl* usr/lib/libnss*
rm usr/lib/libc_malloc_debug.so
strip -g usr/lib/*.o
mv lib/{libmemusage,libpcprofile}.so usr/lib/
popd
%endif
# Build and install:
pushd build-%{target}
%make_build install_root=%{glibc_sysroot} install
@ -1591,7 +1640,17 @@ pushd %{glibc_sysroot}/%{sysroot_prefix}
mkdir -p usr/lib usr/lib64
cp -a %{glibc_sysroot}/%{_prefix}/include usr/.
%ifarch x86_64
# 32-bit headers for glibc32 don't go in the sysroot.
rm usr/include/gnu/*-32.h
%endif
for lib in lib lib64; do
%ifarch x86_64
if [ "$lib" = "lib" ]; then
# 32-bit libraries built for glibc32 don't go in the sysroot.
continue
fi
%endif
for pfx in "" %{_prefix}/; do
if test -d %{glibc_sysroot}/$pfx$lib ; then
# Implement UsrMove: everything goes into usr/$lib. Only
@ -1675,6 +1734,8 @@ popd
# - File list with the .so symbolic links for NSS packages.
# * compat-libpthread-nonshared.filelist.
# - File list for compat-libpthread-nonshared subpackage.
# * glibc32.filelist
# - Files for the glibc32 packages.
# Create the main file lists. This way we can append to any one of them later
# wihtout having to create it. Note these are removed at the start of the
@ -1693,6 +1754,9 @@ touch nss_db.filelist
touch nss_hesiod.filelist
touch nss-devel.filelist
touch compat-libpthread-nonshared.filelist
%ifarch x86_64
touch glibc32.filelist
%endif
###############################################################################
# Master file list, excluding a few things.
@ -1779,6 +1843,12 @@ cat master.filelist \
-e '/libnsl' \
-e 'glibc-benchtests' \
-e 'aux-cache' \
%ifarch x86_64
%dnl Exclude 32-bit libraries built for glibc32.
-e '/lib/.*\.o' \
-e '/lib/.*\.a' \
-e '/lib/.*\.so.*' \
%endif
> glibc.filelist
# Add specific files:
@ -1788,9 +1858,18 @@ for module in compat files dns; do
cat master.filelist \
| grep -E \
-e "/libnss_$module(\.so\.[0-9.]+|-[0-9.]+\.so)$" \
%ifarch x86_64
%dnl Exclude 32-bit libraries built for glibc32.
| grep -v -e /lib/lib \
%endif
>> glibc.filelist
done
grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist >> glibc.filelist
grep -e "libmemusage.so" -e "libpcprofile.so" master.filelist \
%ifarch x86_64
%dnl Exclude 32-bit libraries built for glibc32.
| grep -v -e /lib/lib \
%endif
>> glibc.filelist
###############################################################################
# glibc-gconv-extra
@ -1831,6 +1910,10 @@ other_static_library_pattern='/libpthread_nonshared\.a'
grep '%{_libdir}/lib.*\.a' master.filelist \
| grep "$devel_static_library_pattern" \
| grep -v "$other_static_library_pattern" \
%ifarch x86_64
%dnl Exclude 32-bit libraries built for glibc32.
| grep -v '/lib/.*\.a' \
%endif
> devel.filelist
# Put all of the object files and *.so (not the versioned ones) into the
@ -1843,6 +1926,10 @@ grep '%{_libdir}/lib.*\.so' < master.filelist >> devel.filelist
sed -i -e '\,libmemusage.so,d' \
-e '\,libpcprofile.so,d' \
-e '\,/libnss_[a-z]*\.so$,d' \
%ifarch x86_64
%dnl Exclude 32-bit libraries built for glibc32.
-e '\,/lib/.*\.so$,d' \
%endif
devel.filelist
%if %{glibc_autorequires}
@ -1874,8 +1961,17 @@ grep '%{_docdir}' master.filelist >> doc.filelist
# across all multilib packages. We must keep gnu/stubs.h and gnu/lib-names.h
# in the glibc-headers package, but the -32, -64, -64-v1, and -64-v2 versions
# go into glibc-devel.
%ifarch x86_64
# Hardcode 32-bit and 64-bit header names here, so that 32-bit headers end up
# in glibc32.
grep '%{_prefix}/include/gnu/stubs-64\.h$' < master.filelist >> devel.filelist || :
grep '%{_prefix}/include/gnu/lib-names-64\.h$' < master.filelist >> devel.filelist || :
grep '%{_prefix}/include/gnu/stubs-32\.h$' < master.filelist >> glibc32.filelist || :
grep '%{_prefix}/include/gnu/lib-names-32\.h$' < master.filelist >> glibc32.filelist || :
%else
grep '%{_prefix}/include/gnu/stubs-.*\.h$' < master.filelist >> devel.filelist || :
grep '%{_prefix}/include/gnu/lib-names-.*\.h$' < master.filelist >> devel.filelist || :
%endif
# Put the include files into headers file list.
grep '%{_prefix}/include' < master.filelist \
| grep -E -v '%{_prefix}/include/gnu/stubs-.*\.h$' \
@ -1895,6 +1991,10 @@ grep '%{_prefix}/include' < master.filelist >> devel.filelist
grep '%{_libdir}/lib.*\.a' < master.filelist \
| grep -v "$devel_static_library_pattern" \
| grep -v "$other_static_library_pattern" \
%ifarch x86_64
%dnl Exclude 32-bit libraries built for glibc32.
| grep -v '/lib/.*\.a' \
%endif
> static.filelist
###############################################################################
@ -1992,6 +2092,15 @@ echo "%{_prefix}/libexec/glibc-benchtests/validate_benchout.py*" >> benchtests.f
###############################################################################
echo "%{_libdir}/libpthread_nonshared.a" >> compat-libpthread-nonshared.filelist
###############################################################################
# glibc32
###############################################################################
%ifarch x86_64
grep '/lib/.*\.o$' master.filelist >> glibc32.filelist
grep '/lib/.*\.a$' master.filelist >> glibc32.filelist
grep '/lib/.*\.so' master.filelist >> glibc32.filelist
%endif
##############################################################################
# Run the glibc testsuite
##############################################################################
@ -2059,8 +2168,14 @@ echo ====================PLT RELOCS END==================
# link and then pick the first loader (although there should be only
# one). Use -maxdepth 2 to avoid descending into the /sys-root/
# sub-tree. See wrap-find-debuginfo.sh.
%ifarch x86_64
# Hardcode the patch to avoid picking up the 32-bit dynamic linker from
# glibc32; both 32-bit and 64-bit dynamic linkers will be present.
ldso_path="%{glibc_sysroot}/lib64/ld-linux-x86-64.so.2"
%else
ldso_path="$(find %{glibc_sysroot}/ -maxdepth 2 -regextype posix-extended \
-regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f | LC_ALL=C sort | head -n1)"
%endif
run_ldso="$ldso_path --library-path %{glibc_sysroot}/%{_lib}"
# Show the auxiliary vector as seen by the new library
@ -2344,7 +2459,18 @@ update_gconv_modules_cache ()
%{sysroot_prefix}
%endif
%ifarch x86_64
%files -f glibc32.filelist -n glibc32
%endif
%changelog
* Tue Mar 26 2024 Florian Weimer <fweimer@redhat.com> - 2.39-6
- Do not generate ELF dependency information for glibc32
* Tue Mar 26 2024 Joseph Myers <josmyers@redhat.com> - 2.39-5
- Build glibc32 binary package from glibc sources as part of x86_64 build,
not from glibc32 SRPM that contains binaries from i686 RPM build.
* Tue Mar 19 2024 Arjun Shankar <arjun@redhat.com> - 2.39-4
- Sync with upstream branch release/2.39/master,
commit: 71fcdba577884627c3ee4e43beb915da752efb1f:

View File

@ -43,6 +43,11 @@ for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \
-regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do
if test -z "$ldso_path" ; then
ldso_path="$ldso_candidate"
elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then
# x86_64 with 32-bit libc built for glibc32 as well. Finding
# multiple dynamic linkers is expected, not a bug; ensure the
# 64-bit one is used.
ldso_path="$sysroot_path/lib64/ld-linux-x86-64.so.2"
else
echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate"
exit 1
@ -54,6 +59,11 @@ libc_path=
for libc_candidate in `find "$sysroot_path" -maxdepth 2 -name libc.so.6`; do
if test -z "$libc_path" ; then
libc_path="$libc_candidate"
elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then
# x86_64 with 32-bit libc built for glibc32 as well. The test
# here uses ld.so paths, not libc paths, to ensure it doesn't
# apply on any other architecture.
libc_path="$sysroot_path/lib64/libc.so.6"
else
echo "error: multiple libc.so.6 candidates: $libc_path, $libc_candidate"
exit 1