Module: OS::Linux::Ld Private

Defined in:
os/linux/ld.rb

Overview

This module is part of a private API. This module may only be used in the Homebrew/brew repository. Third parties should avoid using this module if possible, as it may be removed or changed without warning.

Helper functions for querying ld information.

Constant Summary collapse

DYNAMIC_LINKERS =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

This is a list of known paths to the host dynamic linker on Linux if the host glibc is new enough. Brew will fail to create a symlink for ld.so if the host linker cannot be found in this list.

%w[
  /lib64/ld-linux-x86-64.so.2
  /lib64/ld64.so.2
  /lib/ld-linux.so.3
  /lib/ld-linux.so.2
  /lib/ld-linux-aarch64.so.1
  /lib/ld-linux-armhf.so.3
  /system/bin/linker64
  /system/bin/linker
].freeze

Class Method Summary collapse

Class Method Details

.ld_so_diagnostics(brewed: true) ⇒ String

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • brewed (Boolean) (defaults to: true)

Returns:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'os/linux/ld.rb', line 33

def self.ld_so_diagnostics(brewed: true)
  @ld_so_diagnostics ||= T.let({}, T.nilable(T::Hash[Pathname, String]))

  ld_so_target = if brewed
    ld_so = HOMEBREW_PREFIX/"lib/ld.so"
    return "" unless ld_so.exist?

    ld_so.readlink
  else
    ld_so = system_ld_so
    return "" unless ld_so&.exist?

    ld_so
  end

  @ld_so_diagnostics[ld_so_target] ||= begin
    ld_so_output = Utils.popen_read(ld_so, "--list-diagnostics")
    ld_so_output if $CHILD_STATUS.success?
  end

  @ld_so_diagnostics[ld_so_target].to_s
end

.library_paths(conf_path = "ld.so.conf", brewed: true) ⇒ Array<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • conf_path (Pathname, String) (defaults to: "ld.so.conf")
  • brewed (Boolean) (defaults to: true)

Returns:



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'os/linux/ld.rb', line 81

def self.library_paths(conf_path = "ld.so.conf", brewed: true)
  conf_file = Pathname(sysconfdir(brewed:))/conf_path
  return [] unless conf_file.exist?
  return [] unless conf_file.file?
  return [] unless conf_file.readable?

  @library_paths_cache ||= T.let({}, T.nilable(T::Hash[String, T::Array[String]]))
  cache_key = conf_file.to_s
  if (cached_library_path_contents = @library_paths_cache[cache_key])
    return cached_library_path_contents
  end

  paths = Set.new
  directory = conf_file.realpath.dirname

  conf_file.open("r") do |file|
    file.each_line do |line|
      # Remove comments and leading/trailing whitespace
      line.strip!
      line.sub!(/\s*#.*$/, "")

      if line.start_with?(/\s*include\s+/)
        wildcard = Pathname(line.sub(/^\s*include\s+/, "")).expand_path(directory)

        Dir.glob(wildcard.to_s).each do |include_file|
          paths += library_paths(include_file)
        end
      elsif line.empty?
        next
      else
        paths << line
      end
    end
  end

  @library_paths_cache[cache_key] = paths.to_a
end

.sysconfdir(brewed: true) ⇒ String

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • brewed (Boolean) (defaults to: true)

Returns:



57
58
59
60
61
62
63
64
# File 'os/linux/ld.rb', line 57

def self.sysconfdir(brewed: true)
  fallback_sysconfdir = "/etc"

  match = ld_so_diagnostics(brewed:).match(/path.sysconfdir="(.+)"/)
  return fallback_sysconfdir unless match

  match.captures.compact.first || fallback_sysconfdir
end

.system_dirs(brewed: true) ⇒ Array<String>

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • brewed (Boolean) (defaults to: true)

Returns:



67
68
69
70
71
72
73
74
75
76
77
78
# File 'os/linux/ld.rb', line 67

def self.system_dirs(brewed: true)
  dirs = []

  ld_so_diagnostics(brewed:).split("\n").each do |line|
    match = line.match(/path.system_dirs\[0x.*\]="(.*)"/)
    next unless match

    dirs << match.captures.compact.first
  end

  dirs
end

.system_ld_soPathname?

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

The path to the system's dynamic linker or nil if not found

Returns:



24
25
26
27
28
29
30
# File 'os/linux/ld.rb', line 24

def self.system_ld_so
  @system_ld_so ||= T.let(nil, T.nilable(Pathname))
  @system_ld_so ||= begin
    linker = DYNAMIC_LINKERS.find { |s| File.executable? s }
    Pathname(linker) if linker
  end
end