Module: LLDB::BuildDiscovery

Defined in:
ext/lldb/discovery.rb

Defined Under Namespace

Classes: Candidate

Constant Summary collapse

DEFAULT_PREFIXES =
[
  '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr',
  '/Library/Developer/CommandLineTools/usr',
  '/opt/homebrew/opt/llvm',
  '/usr/local/opt/llvm',
  '/usr',
  '/usr/local'
].freeze

Class Method Summary collapse

Class Method Details

.candidate_for_llvm_config(llvm_config) ⇒ Object



43
44
45
46
47
48
49
# File 'ext/lldb/discovery.rb', line 43

def candidate_for_llvm_config(llvm_config)
  include_dir = command_output(llvm_config, '--includedir')
  lib_dir = command_output(llvm_config, '--libdir')
  return unless include_dir && lib_dir

  Candidate.new(include_dir: include_dir, lib_dir: lib_dir, llvm_config: llvm_config)
end

.candidate_for_prefix(prefix) ⇒ Object



51
52
53
54
55
56
57
58
59
60
# File 'ext/lldb/discovery.rb', line 51

def candidate_for_prefix(prefix)
  return unless prefix

  include_dir = File.join(prefix, 'include')
  lib_dir = %w[lib lib64].map { |name| File.join(prefix, name) }.find do |path|
    File.directory?(path)
  end

  Candidate.new(include_dir: include_dir, lib_dir: lib_dir)
end

.candidates(options = {}, env: ENV, path: ENV.fetch('PATH', '')) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'ext/lldb/discovery.rb', line 20

def candidates(options = {}, env: ENV, path: ENV.fetch('PATH', ''))
  explicit_include = options[:include] || options[:include_dir]
  explicit_lib = options[:lib] || options[:lib_dir]
  explicit_dir = options[:dir] || options[:lldb_dir] || env['LLDB_DIR']

  candidates = []
  candidates << Candidate.new(include_dir: explicit_include, lib_dir: explicit_lib) if explicit_include || explicit_lib

  if explicit_dir
    candidates << candidate_for_prefix(explicit_dir)
  end

  llvm_config_paths(path).each do |llvm_config|
    candidates << candidate_for_llvm_config(llvm_config)
  end

  prefix_paths(explicit_dir, env: env).each do |prefix|
    candidates << candidate_for_prefix(prefix)
  end

  candidates.compact.uniq { |candidate| [candidate.include_dir, candidate.lib_dir] }
end

.command_output(*command) ⇒ Object



90
91
92
93
94
95
# File 'ext/lldb/discovery.rb', line 90

def command_output(*command)
  output = IO.popen(command, &:read).strip
  output.empty? ? nil : output
rescue SystemCallError
  nil
end

.llvm_config_paths(path) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'ext/lldb/discovery.rb', line 71

def llvm_config_paths(path)
  executables = path.split(File::PATH_SEPARATOR).flat_map do |directory|
    next [] unless File.directory?(directory)

    Dir.children(directory).filter_map do |name|
      next unless name.match?(/\Allvm-config(?:-\d+(?:\.\d+)*)?\z/)

      executable = File.join(directory, name)
      executable if File.executable?(executable)
    end
  end

  unique_executables = executables.uniq
  unversioned = unique_executables.select { |path| File.basename(path) == 'llvm-config' }
  versioned = unique_executables.reject { |path| File.basename(path) == 'llvm-config' }

  unversioned + versioned.sort_by { |path| version_key(path) }.reverse
end

.prefix_paths(explicit_dir, env: ENV) ⇒ Object



62
63
64
65
66
67
68
69
# File 'ext/lldb/discovery.rb', line 62

def prefix_paths(explicit_dir, env: ENV)
  paths = []
  paths << explicit_dir if explicit_dir
  paths << env['LLVM_PREFIX'] if env['LLVM_PREFIX']
  paths.concat(DEFAULT_PREFIXES)
  paths.concat(Dir.glob('/usr/lib/llvm-*').sort_by { |path| version_key(path) }.reverse)
  paths.compact.uniq
end

.version_key(value) ⇒ Object



97
98
99
# File 'ext/lldb/discovery.rb', line 97

def version_key(value)
  value.to_s.scan(/\d+/).map(&:to_i)
end