1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#!/usr/bin/env python3
# Locate an LLVM install that ships the LLDB headers, mirroring the search order
# the old premake5.lua used. Meson calls this at configure time and parses the
# KEY=value lines below; run it by hand to see what would be picked.
#
# Precedence: -Dllvm_prefix (argv[1]) -> $LLVM_PREFIX -> vendored ext/llvm ->
# `llvm-config --prefix` -> per-platform well-known locations. A candidate only
# counts if it actually contains include/lldb.
#
# Output (stdout), only when a usable prefix is found:
# prefix=<dir>
# incdir=<dir>/include
# libdir=<dir>/lib
# lib=<full path to liblldb>
# dll=<path> (zero or more, Windows runtime libraries only)
# Exit status is non-zero when nothing usable was found.
import glob
import os
import platform
import subprocess
import sys
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
VENDORED = os.path.join(REPO_ROOT, "ext", "llvm")
def norm(path):
# forward slashes so the value can be baked into a C string literal without
# a backslash being read as an escape (matters for HSDBG_LLVM_PREFIX)
return os.path.abspath(path).replace("\\", "/")
def usable(candidate):
if not candidate:
return None
candidate = candidate.strip()
if not candidate:
return None
prefix = norm(candidate)
if os.path.isdir(os.path.join(prefix, "include", "lldb")):
return prefix
return None
def command_output(*args):
try:
out = subprocess.run(
args, capture_output=True, text=True, check=False
)
except OSError:
return None
if out.returncode != 0:
return None
return out.stdout.strip() or None
def newest_of(pattern):
matches = sorted(glob.glob(pattern))
for candidate in reversed(matches):
prefix = usable(candidate)
if prefix:
return prefix
return None
def find_prefix(override):
prefix = usable(override) or usable(os.environ.get("LLVM_PREFIX"))
if prefix:
return prefix
prefix = usable(VENDORED)
if prefix:
return prefix
prefix = usable(command_output("llvm-config", "--prefix"))
if prefix:
return prefix
host = platform.system()
if host == "Windows":
program_files = os.environ.get("ProgramFiles")
if program_files:
prefix = usable(os.path.join(program_files, "LLVM"))
if prefix:
return prefix
return newest_of("C:/Program Files/LLVM*")
if host == "Darwin":
return usable(command_output("brew", "--prefix", "llvm"))
if host == "Linux":
return newest_of("/usr/lib/llvm-*") or newest_of("/usr/local/llvm*")
return None
def lldb_library(libdir):
host = platform.system()
if host == "Windows":
names = ["liblldb.lib"]
elif host == "Darwin":
names = ["liblldb.dylib"]
else:
names = ["liblldb.so"]
for name in names:
candidate = os.path.join(libdir, name)
if os.path.isfile(candidate):
return norm(candidate)
versioned = sorted(glob.glob(os.path.join(libdir, "liblldb.so.*")))
if versioned:
return norm(versioned[-1])
# nothing on disk yet (e.g. a cross setup); hand back the expected path so
# the caller gets a clear link-time error rather than a silent misconfigure
return norm(os.path.join(libdir, names[0]))
def windows_dlls(prefix):
bindir = os.path.join(prefix, "bin")
runtimes = glob.glob(os.path.join(bindir, "liblldb.dll"))
runtimes += glob.glob(os.path.join(bindir, "python*.dll"))
if not runtimes:
runtimes = [os.path.join(bindir, "liblldb.dll")]
return [norm(path) for path in runtimes]
def main():
override = sys.argv[1] if len(sys.argv) > 1 else ""
prefix = find_prefix(override)
if not prefix:
sys.stderr.write("no llvm with lldb headers found\n")
return 1
incdir = norm(os.path.join(prefix, "include"))
libdir = norm(os.path.join(prefix, "lib"))
print("prefix=" + prefix)
print("incdir=" + incdir)
print("libdir=" + libdir)
print("lib=" + lldb_library(libdir))
if platform.system() == "Windows":
for dll in windows_dlls(prefix):
print("dll=" + dll)
return 0
if __name__ == "__main__":
sys.exit(main())
|