diff --git a/Library/Homebrew/extend/os/linux/development_tools.rb b/Library/Homebrew/extend/os/linux/development_tools.rb index 35c83585f9..7707a9eed4 100644 --- a/Library/Homebrew/extend/os/linux/development_tools.rb +++ b/Library/Homebrew/extend/os/linux/development_tools.rb @@ -8,10 +8,15 @@ class DevelopmentTools sig { params(tool: String).returns(T.nilable(Pathname)) } def locate(tool) (@locate ||= {}).fetch(tool) do |key| - @locate[key] = if (path = HOMEBREW_PREFIX/"bin/#{tool}").executable? - path - elsif File.executable?(path = "/usr/bin/#{tool}") - Pathname.new path + @locate[key] = if build_system_too_old? && + (binutils_path = HOMEBREW_PREFIX/"opt/binutils/bin/#{tool}").executable? + binutils_path + elsif build_system_too_old? && (glibc_path = HOMEBREW_PREFIX/"opt/glibc/bin/#{tool}").executable? + glibc_path + elsif (homebrew_path = HOMEBREW_PREFIX/"bin/#{tool}").executable? + homebrew_path + elsif File.executable?(system_path = "/usr/bin/#{tool}") + Pathname.new system_path end end end @@ -30,7 +35,7 @@ class DevelopmentTools sig { returns(T::Boolean) } def system_gcc_too_old? - gcc_version("gcc") < OS::LINUX_GCC_CI_VERSION + gcc_version("/usr/bin/gcc") < OS::LINUX_GCC_CI_VERSION end sig { returns(T::Hash[String, T.nilable(String)]) } diff --git a/Library/Homebrew/extend/os/linux/install.rb b/Library/Homebrew/extend/os/linux/install.rb index b4f9cfdc8e..6bf944c08e 100644 --- a/Library/Homebrew/extend/os/linux/install.rb +++ b/Library/Homebrew/extend/os/linux/install.rb @@ -38,13 +38,13 @@ module Homebrew def perform_preinstall_checks(all_fatal: false, cc: nil) generic_perform_preinstall_checks(all_fatal: all_fatal, cc: cc) symlink_ld_so - symlink_gcc_libs + setup_preferred_gcc_libs end def global_post_install generic_global_post_install symlink_ld_so - symlink_gcc_libs + setup_preferred_gcc_libs end def check_cpu @@ -64,36 +64,71 @@ module Homebrew def symlink_ld_so brew_ld_so = HOMEBREW_PREFIX/"lib/ld.so" - return if brew_ld_so.readable? - ld_so = HOMEBREW_PREFIX/"opt/glibc/lib/ld-linux-x86-64.so.2" + ld_so = HOMEBREW_PREFIX/"opt/glibc/bin/ld.so" unless ld_so.readable? ld_so = DYNAMIC_LINKERS.find { |s| File.executable? s } - raise "Unable to locate the system's dynamic linker" unless ld_so + if ld_so.blank? + raise "Unable to locate the system's dynamic linker" unless brew_ld_so.readable? + + return + end end + return if brew_ld_so.readable? && (brew_ld_so.readlink == ld_so) + FileUtils.mkdir_p HOMEBREW_PREFIX/"lib" FileUtils.ln_sf ld_so, brew_ld_so end private_class_method :symlink_ld_so - def symlink_gcc_libs + def setup_preferred_gcc_libs gcc_opt_prefix = HOMEBREW_PREFIX/"opt/#{OS::LINUX_PREFERRED_GCC_RUNTIME_FORMULA}" + glibc_installed = (HOMEBREW_PREFIX/"opt/glibc/bin/ld.so").readable? + + return unless gcc_opt_prefix.readable? + + if glibc_installed + ld_so_conf_d = HOMEBREW_PREFIX/"etc/ld.so.conf.d" + unless ld_so_conf_d.exist? + ld_so_conf_d.mkpath + FileUtils.chmod "go-w", ld_so_conf_d + end + + # Add gcc to ld search paths + ld_gcc_conf = ld_so_conf_d/"50-homebrew-preferred-gcc.conf" + unless ld_gcc_conf.exist? + ld_gcc_conf.atomic_write <<~EOS + # This file is generated by Homebrew. Do not modify. + #{gcc_opt_prefix}/lib/gcc/#{PREFERRED_GCC_RUNTIME_VERSION} + EOS + FileUtils.chmod "u=rw,go-wx", ld_gcc_conf + + FileUtils.rm_f HOMEBREW_PREFIX/"etc/ld.so.cache" + system HOMEBREW_PREFIX/"opt/glibc/sbin/ldconfig" + end + else + odie "#{HOMEBREW_PREFIX}/lib does not exist!" unless (HOMEBREW_PREFIX/"lib").readable? + end GCC_RUNTIME_LIBS.each do |library| - gcc_library = gcc_opt_prefix/"lib/gcc/#{PREFERRED_GCC_RUNTIME_VERSION}/#{library}" gcc_library_symlink = HOMEBREW_PREFIX/"lib/#{library}" - # Skip if the link target doesn't exist. - next unless gcc_library.readable? - # Also skip if the symlink already exists. - next if gcc_library_symlink.readable? && (gcc_library_symlink.readlink == gcc_library) + if glibc_installed + # Remove legacy symlinks + FileUtils.rm gcc_library_symlink if gcc_library_symlink.symlink? + else + gcc_library = gcc_opt_prefix/"lib/gcc/#{PREFERRED_GCC_RUNTIME_VERSION}/#{library}" + # Skip if the link target doesn't exist. + next unless gcc_library.readable? - odie "#{HOMEBREW_PREFIX}/lib does not exist!" unless (HOMEBREW_PREFIX/"lib").readable? + # Also skip if the symlink already exists. + next if gcc_library_symlink.readable? && (gcc_library_symlink.readlink == gcc_library) - FileUtils.ln_sf gcc_library, gcc_library_symlink + FileUtils.ln_sf gcc_library, gcc_library_symlink + end end end - private_class_method :symlink_gcc_libs + private_class_method :setup_preferred_gcc_libs end end