@@ -5,37 +5,69 @@ module OS
55 module Linux
66 # Helper functions for querying `ld` information.
77 module Ld
8- sig { returns ( String ) }
9- def self . brewed_ld_so_diagnostics
10- @brewed_ld_so_diagnostics ||= T . let ( { } , T . nilable ( T ::Hash [ Pathname , String ] ) )
8+ # This is a list of known paths to the host dynamic linker on Linux if
9+ # the host glibc is new enough. Brew will fail to create a symlink for
10+ # ld.so if the host linker cannot be found in this list.
11+ DYNAMIC_LINKERS = %w[
12+ /lib64/ld-linux-x86-64.so.2
13+ /lib64/ld64.so.2
14+ /lib/ld-linux.so.3
15+ /lib/ld-linux.so.2
16+ /lib/ld-linux-aarch64.so.1
17+ /lib/ld-linux-armhf.so.3
18+ /system/bin/linker64
19+ /system/bin/linker
20+ ] . freeze
21+
22+ # The path to the system's dynamic linker or `nil` if not found
23+ sig { returns ( T . nilable ( Pathname ) ) }
24+ def self . system_ld_so
25+ @system_ld_so ||= T . let ( nil , T . nilable ( Pathname ) )
26+ @system_ld_so ||= begin
27+ linker = DYNAMIC_LINKERS . find { |s | File . executable? s }
28+ Pathname ( linker ) if linker
29+ end
30+ end
31+
32+ sig { params ( brewed : T ::Boolean ) . returns ( String ) }
33+ def self . ld_so_diagnostics ( brewed : true )
34+ @ld_so_diagnostics ||= T . let ( { } , T . nilable ( T ::Hash [ Pathname , String ] ) )
1135
12- brewed_ld_so = HOMEBREW_PREFIX /"lib/ld.so"
13- return "" unless brewed_ld_so . exist?
36+ ld_so_target = if brewed
37+ ld_so = HOMEBREW_PREFIX /"lib/ld.so"
38+ return "" unless ld_so . exist?
39+
40+ ld_so . readlink
41+ else
42+ ld_so = system_ld_so
43+ return "" unless ld_so &.exist?
44+
45+ ld_so
46+ end
1447
15- brewed_ld_so_target = brewed_ld_so . readlink
16- @brewed_ld_so_diagnostics [ brewed_ld_so_target ] ||= begin
17- ld_so_output = Utils . popen_read ( brewed_ld_so , "--list-diagnostics" )
48+ @ld_so_diagnostics [ ld_so_target ] ||= begin
49+ ld_so_output = Utils . popen_read ( ld_so , "--list-diagnostics" )
1850 ld_so_output if $CHILD_STATUS. success?
1951 end
2052
21- @brewed_ld_so_diagnostics [ brewed_ld_so_target ] . to_s
53+ @ld_so_diagnostics [ ld_so_target ] . to_s
2254 end
2355
24- sig { returns ( String ) }
25- def self . sysconfdir
56+ sig { params ( brewed : T :: Boolean ) . returns ( String ) }
57+ def self . sysconfdir ( brewed : true )
2658 fallback_sysconfdir = "/etc"
2759
28- match = brewed_ld_so_diagnostics . match ( /path.sysconfdir="(.+)"/ )
60+ match = ld_so_diagnostics ( brewed : ) . match ( /path.sysconfdir="(.+)"/ )
2961 return fallback_sysconfdir unless match
3062
3163 match . captures . compact . first || fallback_sysconfdir
3264 end
3365
34- sig { returns ( T ::Array [ String ] ) }
35- def self . system_dirs
66+ sig { params ( brewed : T :: Boolean ) . returns ( T ::Array [ String ] ) }
67+ def self . system_dirs ( brewed : true )
3668 dirs = [ ]
3769
38- brewed_ld_so_diagnostics . split ( "\n " ) . each do |line |
70+ ld_so_diagnostics ( brewed : ) . split ( "\n " ) . each do |line |
3971 match = line . match ( /path.system_dirs\[ 0x.*\] ="(.*)"/ )
4072 next unless match
4173
@@ -45,9 +77,9 @@ def self.system_dirs
4577 dirs
4678 end
4779
48- sig { params ( conf_path : T . any ( Pathname , String ) ) . returns ( T ::Array [ String ] ) }
49- def self . library_paths ( conf_path = Pathname ( sysconfdir ) / "ld.so.conf" )
50- conf_file = Pathname ( conf_path )
80+ sig { params ( conf_path : T . any ( Pathname , String ) , brewed : T :: Boolean ) . returns ( T ::Array [ String ] ) }
81+ def self . library_paths ( conf_path = "ld.so.conf" , brewed : true )
82+ conf_file = Pathname ( sysconfdir ( brewed : ) ) / conf_path
5183 return [ ] unless conf_file . exist?
5284 return [ ] unless conf_file . file?
5385 return [ ] unless conf_file . readable?
@@ -68,8 +100,7 @@ def self.library_paths(conf_path = Pathname(sysconfdir)/"ld.so.conf")
68100 line . sub! ( /\s *#.*$/ , "" )
69101
70102 if line . start_with? ( /\s *include\s +/ )
71- include_path = Pathname ( line . sub ( /^\s *include\s +/ , "" ) ) . expand_path
72- wildcard = include_path . absolute? ? include_path : directory /include_path
103+ wildcard = Pathname ( line . sub ( /^\s *include\s +/ , "" ) ) . expand_path ( directory )
73104
74105 Dir . glob ( wildcard . to_s ) . each do |include_file |
75106 paths += library_paths ( include_file )
0 commit comments