glibc 2.37 patchelf workaround for ChromeOS broken glibc 2.37 & fix upgrades for is_fake pkgs (#10272)

* glibc 2.37 patchelf workaround for ChromeOS broken glibc 2.37

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* remove error message

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* handle libstdc++ modification in glibc postinstall

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* add postinstall to glibc_lib237

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* remove instance variables

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* remove more instance variables

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* suggested changes

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* use float conversions before comparison

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* clarify logic

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

* Fix upgrade loop for is_fake packages.

Signed-off-by: Satadru Pramanik <satadru@gmail.com>

---------

Signed-off-by: Satadru Pramanik <satadru@gmail.com>
This commit is contained in:
Satadru Pramanik, DO, MPH, MEng
2024-08-09 22:58:47 -04:00
committed by GitHub
parent 4ee714c8c8
commit 0f83f188ea
10 changed files with 225 additions and 109 deletions

View File

@@ -6,21 +6,23 @@ class Glibc_build237 < Package
license 'LGPL-2.1+, BSD, HPND, ISC, inner-net, rc, and PCRE'
compatibility 'all'
binary_compression 'tar.zst'
@libc_version = LIBC_VERSION
version '2.37'
# @libc_version = LIBC_VERSION
@libc_version = '2.37'
version '2.37-1'
source_url 'https://github.com/bminor/glibc.git'
git_hashtag 'glibc-2.37'
binary_sha256({
aarch64: 'd9cac82b17d463b98caf5c29e143775d3aeed29df3851207ad930d9c5b4c391b',
armv7l: 'd9cac82b17d463b98caf5c29e143775d3aeed29df3851207ad930d9c5b4c391b',
x86_64: '07754223434ad59930ebca10f0adbd390700ebd93a43853b183ed30f0a0a33ca'
aarch64: 'fffbe32d69e3d972c9c845e8fa244159d7ac8b82ae9f07206c7189b20e3457c8',
armv7l: 'fffbe32d69e3d972c9c845e8fa244159d7ac8b82ae9f07206c7189b20e3457c8',
x86_64: '890a2ba75346498bb20165d55ee2d91bcb57d8c65df485029a5b8a20a5f73c19'
})
depends_on 'gawk' => :build
depends_on 'filecmd' # L Fixes creating symlinks on a fresh install.
depends_on 'libidn2' => :build
depends_on 'texinfo' => :build
depends_on 'patchelf' # L
conflicts_ok
no_env_options
@@ -37,8 +39,21 @@ class Glibc_build237 < Package
system "sed -i 's,verbose,locale_verbose,g' fedora/build-locale-archive.c"
system "sed -i 's,be_quiet,locale_be_quiet,g' fedora/build-locale-archive.c"
@googlesource_branch = 'release-R123-15786.B'
@googlesource_branch = 'release-R128-15964.B'
system "git clone --depth=1 -b #{@googlesource_branch} https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay googlesource"
# We need to avoid this patch to preserve float128. Otherwise strtof128,
# strfromf128, and __strtof128_nan, are not available in our glibc.
# This still requires hackery to avoid issues, as handled below by
# renaming our libc.so.6 to libC.so.6 and using patchelf to add
# needs for our libm.so.6 as well as the system provided libc.so.6.
# gcc_lib's stdc++.so.6 also needs to be told to need our glibc's
# renamed libC.so.6. Additionally, packages on these systems need to
# be built with CREW_LINKER_FLAGS=' /usr/local/lib64/libC.so.6 ' set.
#
FileUtils.rm 'googlesource/sys-libs/glibc/files/local/glibc-2.37/0003-Disable-float128-support-for-x86_64-x86.patch'
# Please submit suggestions for less hacky workarounds.
#
Dir.glob('googlesource/sys-libs/glibc/files/local/glibc-2.37/*.patch').each do |patch|
puts "patch -Np1 < #{patch} || true" if @opt_verbose
system "patch -Np1 -F 10 -i #{patch} || true"
@@ -98,10 +113,11 @@ class Glibc_build237 < Package
system "sed -i 's,install-symbolic-link,/bin/true,g' ../Makefile"
system "sed -i 's,symbolic-link-prog := $(elf-objpfx)sln,symbolic-link-prog := /bin/true,g' ../Makerules"
when 'x86_64'
# https://source.chromium.org/chromiumos/_/chromium/chromiumos/overlays/chromiumos-overlay/+/a73162d56fd689b26812282c3f9bc4f2b5a67530:sys-libs/glibc/glibc-2.37.ebuild
File.write('configparms', "slibdir=#{CREW_LIB_PREFIX}", mode: 'a+')
system "CFLAGS='-fuse-ld=mold -pipe -O2 -fipa-pta \
-fno-semantic-interposition -falign-functions=32 \
-fdevirtualize-at-ltrans' \
-fdevirtualize-at-ltrans -mstackrealign' \
../configure \
--prefix=#{CREW_PREFIX} \
--libdir=#{CREW_LIB_PREFIX} \
@@ -171,52 +187,72 @@ class Glibc_build237 < Package
end
if @libc_version.to_f >= 2.32
system "install -Dt #{CREW_DEST_PREFIX}/bin -m755 build-locale-archive"
system "make -j1 DESTDIR=#{CREW_DEST_DIR} localedata/install-locales"
system "make -j1 DESTDIR=#{CREW_DEST_DIR} localedata/install-locales || make -j1 DESTDIR=#{CREW_DEST_DIR} localedata/install-locales"
end
Dir.chdir CREW_DEST_LIB_PREFIX do
puts "System glibc version is #{LIBC_VERSION}.".lightblue
puts 'Creating symlinks to system glibc version to prevent breakage.'.lightblue
case ARCH
when 'aarch64', 'armv7l'
FileUtils.ln_sf "/lib/ld-#{@libc_version}.so", 'ld-linux-armhf.so.3'
FileUtils.ln_sf '/lib/ld-linux-armhf.so.3', 'ld-linux-armhf.so.3'
when 'i686'
FileUtils.ln_sf "/lib/ld-#{@libc_version}.so", 'ld-linux-i686.so.2'
when 'x86_64'
FileUtils.ln_sf "/lib64/ld-#{@libc_version}.so", 'ld-linux-x86-64.so.2'
# newer x86_64 ChromeOS glibc lacks strtof128, strfromf128
# and __strtof128_nan
# when 'x86_64'
# FileUtils.ln_sf '/lib64/ld-linux-x86-64.so.2', 'ld-linux-x86-64.so.2.system'
end
@libraries = %w[ld libBrokenLocale libSegFault libanl libc libcrypt
libdl libm libmemusage libmvec libnsl libnss_compat libnss_db
libnss_dns libnss_files libnss_hesiod libpcprofile libpthread
libthread_db libresolv librlv librt libthread_db-1.0 libutil]
@libraries -= ['libpthread'] if @libc_version.to_f >= 2.35
@libraries.each do |lib|
# Reject entries which aren't libraries ending in .so, and which aren't files.
Dir["/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
@filetype = `file #{f}`.chomp
if ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
g = File.basename(f)
FileUtils.ln_sf f.to_s, "#{CREW_DEST_LIB_PREFIX}/#{g}"
end
end
# Reject entries which aren't libraries ending in .so, and which aren't files.
# Reject text files such as libc.so because they points to files like
# libc_nonshared.a, which are not provided by ChromeOS
Dir["/usr/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
@filetype = `file #{f}`.chomp
puts "f: #{@filetype}" if @opt_verbose
if ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
g = File.basename(f)
FileUtils.ln_sf f.to_s, "#{CREW_DEST_LIB_PREFIX}/#{g}"
elsif @opt_verbose
puts "#{f} excluded because #{@filetype}"
end
if ARCH == 'x86_64'
# Save our copy of libc.so.6
FileUtils.mv File.join(CREW_DEST_LIB_PREFIX, 'libc.so.6'), File.join(CREW_DEST_LIB_PREFIX, 'libC.so.6')
# Make a symlink to the system libc.so.6, which will require patchelf run on it in the postinstall.
FileUtils.ln_sf "/#{ARCH_LIB}/libc.so.6", 'libc.so.6'
## Also save our copy of libm.so.6 since it has the float128 functions.
# @libraries = %w[ld libBrokenLocale libSegFault libanl libc libcrypt
# libdl libmemusage libmvec libnsl libnss_compat libnss_db
# libnss_dns libnss_files libnss_hesiod libpcprofile libpthread
# libthread_db libresolv librlv librt libthread_db-1.0 libutil]
# @libraries -= ['libpthread'] if @libc_version.to_f >= 2.35
# @libraries.each do |lib|
## Reject entries which aren't libraries ending in .so, and which aren't files.
# Dir["/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
# @filetype = `file #{f}`.chomp
# next unless ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
# g = File.basename(f)
# FileUtils.mkdir_p CREW_DEST_LIB_PREFIX
# Dir.chdir(CREW_DEST_LIB_PREFIX) do
# FileUtils.ln_sf f.to_s, g.to_s
# end
# end
## Reject entries which aren't libraries ending in .so, and which aren't files.
## Reject text files such as libc.so because they points to files like
## libc_nonshared.a, which are not provided by ChromeOS
# Dir["/usr/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
# @filetype = `file #{f}`.chomp
# puts "f: #{@filetype}" if @opt_verbose
# if ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
# g = File.basename(f)
# FileUtils.ln_sf f.to_s, "#{CREW_DEST_LIB_PREFIX}/#{g}"
# elsif @opt_verbose
# puts "#{f} excluded because #{@filetype}"
# end
# end
# Link our libm to also require our renamed libC.so.6
# which provides the float128 functions strtof128, strfromf128,
# and __strtof128_nan.
libc_patch_libraries = %w[libm.so.6]
libc_patch_libraries.each do |lib|
system "patchelf --replace-needed libc.so.6 libC.so.6 #{lib}"
end
end
end
end
# Only save libnsl.so.2, since libnsl.so.1 is provided by perl
# For this to work, build on a M107 or newer container.
FileUtils.cp File.realpath("#{CREW_DEST_LIB_PREFIX}/libnsl.so.1"), "#{CREW_DEST_LIB_PREFIX}/libnsl.so.2"
FileUtils.cp File.realpath("#{CREW_DEST_LIB_PREFIX}/libnsl.so.1"), "#{CREW_DEST_LIB_PREFIX}/libnsl.so.2" if LIBC_VERSION.to_f >= 2.35
FileUtils.rm_f "#{CREW_DEST_LIB_PREFIX}/libnsl.so"
FileUtils.rm_f "#{CREW_DEST_LIB_PREFIX}/libnsl.so.1"
@@ -231,49 +267,81 @@ class Glibc_build237 < Package
end
def self.postinstall
if File.exist?("#{CREW_LIB_PREFIX}/libc.so.6")
@crew_libcvertokens = `#{CREW_LIB_PREFIX}/libc.so.6`.lines.first.chomp.split(/\s/)
@libc_version = @crew_libcvertokens[@crew_libcvertokens.find_index('version') + 1].sub!(/[[:punct:]]?$/, '')
puts "Package glibc version is #{@libc_version}.".lightblue
else
@libc_version = LIBC_VERSION
end
@libraries = %w[ld libBrokenLocale libSegFault libanl libc libcrypt
libdl libm libmemusage libmvec libnsl libnss_compat libnss_db
libnss_dns libnss_files libnss_hesiod libpcprofile libpthread
libthread_db libresolv librlv librt libthread_db-1.0 libutil]
@libraries -= ['libpthread'] if @libc_version.to_f >= 2.35
Dir.chdir CREW_LIB_PREFIX do
puts "System glibc version is #{@libc_version}.".lightblue
puts 'Creating symlinks to system glibc version to prevent breakage.'.lightblue
case ARCH
when 'aarch64', 'armv7l'
FileUtils.ln_sf '/lib/ld-linux-armhf.so.3', 'ld-linux-armhf.so.3'
when 'i686'
FileUtils.ln_sf "/lib/ld-#{@libc_version}.so", 'ld-linux-i686.so.2'
when 'x86_64'
FileUtils.ln_sf '/lib64/ld-linux-x86-64.so.2', 'ld-linux-x86-64.so.2'
end
@libraries.each do |lib|
# Reject entries which aren't libraries ending in .so, and which aren't files.
Dir["/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
@filetype = `file #{f}`.chomp
if ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
g = File.basename(f)
FileUtils.ln_sf f.to_s, "#{CREW_LIB_PREFIX}/#{g}"
# Handle broken system glibc affecting system glibc and libm.so.6 on newer x86_64 ChromeOS milestones.
if (ARCH == 'x86_64') && (LIBC_VERSION.to_f >= 2.35)
FileUtils.cp "/#{ARCH_LIB}/libc.so.6", File.join(CREW_LIB_PREFIX, 'libc.so.6.system') and FileUtils.mv File.join(CREW_LIB_PREFIX, 'libc.so.6.system'), File.join(CREW_LIB_PREFIX, 'libc.so.6')
puts "patchelf is needed. Please run: 'crew install patchelf ; crew postinstall #{name}'".lightred unless File.file?(File.join(CREW_PREFIX, 'bin/patchelf'))
# Link the system libc.so.6 to also require our renamed libC.so.6
# which provides the float128 functions strtof128, strfromf128,
# and __strtof128_nan.
libc_patch_libraries = %w[libc.so.6 libm.so.6 libstdc++.so.6]
libc_patch_libraries.keep_if { |lib| File.file?(File.join(CREW_LIB_PREFIX, lib)) }
libc_patch_libraries.delete_if { |lib| Kernel.system "patchelf --print-needed #{File.join(CREW_LIB_PREFIX, lib)} | grep -q libC.so.6" }
return if libc_patch_libraries.empty?
if File.file?(File.join(CREW_LIB_PREFIX, 'libC.so.6'))
Dir.chdir(CREW_LIB_PREFIX) do
libc_patch_libraries.each do |lib|
Kernel.system "patchelf --add-needed libC.so.6 #{lib}" and Kernel.system "patchelf --remove-needed libc.so.6 #{lib}"
puts "#{lib} patched for use with Chromebrew's glibc.".lightgreen
end
end
# Reject entries which aren't libraries ending in .so, and which aren't files.
# Reject text files such as libc.so because they points to files like
# libc_nonshared.a, which are not provided by ChromeOS
Dir["/usr/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
@filetype = `file #{f}`.chomp
puts "f: #{@filetype}" if @opt_verbose
if ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
end
end
unless ARCH == 'x86_64'
if File.exist?("#{CREW_LIB_PREFIX}/libc.so.6")
@crew_libcvertokens = `#{CREW_LIB_PREFIX}/libc.so.6`.lines.first.chomp.split(/\s/)
@libc_version = @crew_libcvertokens[@crew_libcvertokens.find_index('version') + 1].sub!(/[[:punct:]]?$/, '')
puts "Package glibc version is #{@libc_version}.".lightblue
else
@libc_version = LIBC_VERSION
end
@libraries = %w[ld libBrokenLocale libSegFault libanl libc libcrypt
libdl libm libmemusage libmvec libnsl libnss_compat libnss_db
libnss_dns libnss_files libnss_hesiod libpcprofile libpthread
libthread_db libresolv librlv librt libthread_db-1.0 libutil]
@libraries -= ['libpthread'] if @libc_version.to_f >= 2.35
@libraries -= ['libc'] if (@libc_version.to_f >= 2.35) && Kernel.system("patchelf --print-needed #{File.join(CREW_LIB_PREFIX, 'libc.so.6')} | grep -q libC.so.6")
@libraries -= ['libm'] if (@libc_version.to_f >= 2.35) && Kernel.system("patchelf --print-needed #{File.join(CREW_LIB_PREFIX, 'libm.so.6')} | grep -q libC.so.6")
Dir.chdir CREW_LIB_PREFIX do
puts "System glibc version is #{@libc_version}.".lightblue
puts 'Creating symlinks to system glibc version to prevent breakage.'.lightblue
case ARCH
when 'aarch64', 'armv7l'
FileUtils.ln_sf '/lib/ld-linux-armhf.so.3', 'ld-linux-armhf.so.3'
when 'i686'
FileUtils.ln_sf "/lib/ld-#{@libc_version}.so", 'ld-linux-i686.so.2'
# newer x86_64 ChromeOS glibc lacks strtof128, strfromf128
# and __strtof128_nan
# when 'x86_64'
# FileUtils.ln_sf '/lib64/ld-linux-x86-64.so.2', 'ld-linux-x86-64.so.2'
end
@libraries.each do |lib|
# Reject entries which aren't libraries ending in .so, and which aren't files.
Dir["/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
@filetype = `file #{f}`.chomp
next unless ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
g = File.basename(f)
next if Kernel.system "patchelf --print-needed #{File.join(CREW_LIB_PREFIX, g)} | grep -q libC.so.6"
FileUtils.ln_sf f.to_s, "#{CREW_LIB_PREFIX}/#{g}"
elsif @opt_verbose
puts "#{f} excluded because #{@filetype}"
end
# Reject entries which aren't libraries ending in .so, and which aren't files.
# Reject text files such as libc.so because they points to files like
# libc_nonshared.a, which are not provided by ChromeOS
Dir["/usr/#{ARCH_LIB}/#{lib}.so*"].reject { |f| File.directory?(f) }.each do |f|
@filetype = `file #{f}`.chomp
puts "f: #{@filetype}" if @opt_verbose
if ['shared object', 'symbolic link'].any? { |type| @filetype.include?(type) }
g = File.basename(f)
next if Kernel.system "patchelf --print-needed #{File.join(CREW_LIB_PREFIX, g)} | grep -q libC.so.6"
FileUtils.ln_sf f.to_s, "#{CREW_LIB_PREFIX}/#{g}"
elsif @opt_verbose
puts "#{f} excluded because #{@filetype}"
end
end
end
end