brew/Library/Homebrew/os/linux/libstdcxx.rb
Michael Cho f5c11fa342
Check host libstdc++ for brew gcc dependency
For most formulae, the bottles need a minimum libstdc++ rather than a
minimum GCC version. This is particularly important when building on
Ubuntu where the default compiler version is older than libstdc++.

So, checking the host libstdc++ version is a more accurate way to
determine whether brew GCC is needed at runtime. This can be improved in
the future to check symbol versions (e.g. GLIBCXX, CXXABI, GLIBC) which
can allow some bottles to be installed even with older glibc/libstdc++.
2025-09-12 14:15:56 -04:00

48 lines
1.4 KiB
Ruby

# typed: strict
# frozen_string_literal: true
require "os/linux/ld"
module OS
module Linux
# Helper functions for querying `libstdc++` information.
module Libstdcxx
SOVERSION = 6
SONAME = T.let("libstdc++.so.#{SOVERSION}".freeze, String)
sig { returns(T::Boolean) }
def self.below_ci_version?
system_version < LINUX_LIBSTDCXX_CI_VERSION
end
sig { returns(Version) }
def self.system_version
@system_version ||= T.let(nil, T.nilable(Version))
@system_version ||= if (path = system_path)
Version.new("#{SOVERSION}#{path.realpath.basename.to_s.delete_prefix!(SONAME)}")
else
Version::NULL
end
end
sig { returns(T.nilable(Pathname)) }
def self.system_path
@system_path ||= T.let(nil, T.nilable(Pathname))
@system_path ||= find_library(OS::Linux::Ld.library_paths(brewed: false))
@system_path ||= find_library(OS::Linux::Ld.system_dirs(brewed: false))
end
sig { params(paths: T::Array[String]).returns(T.nilable(Pathname)) }
private_class_method def self.find_library(paths)
paths.each do |path|
next if path.start_with?(HOMEBREW_PREFIX)
candidate = Pathname(path)/SONAME
return candidate if candidate.exist? && candidate.elf?
end
nil
end
end
end
end