xref: /openbsd-src/gnu/llvm/lldb/bindings/python/get-python-config.py (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1#!/usr/bin/env python3
2
3import os
4import sys
5import argparse
6import sysconfig
7
8
9def relpath_nodots(path, base):
10    rel = os.path.normpath(os.path.relpath(path, base))
11    assert not os.path.isabs(rel)
12    parts = rel.split(os.path.sep)
13    if parts and parts[0] == '..':
14        raise ValueError(f"{path} is not under {base}")
15    return rel
16
17def main():
18    parser = argparse.ArgumentParser(description="extract cmake variables from python")
19    parser.add_argument("variable_name")
20    args = parser.parse_args()
21    if args.variable_name == "LLDB_PYTHON_RELATIVE_PATH":
22        # LLDB_PYTHON_RELATIVE_PATH is the relative path from lldb's prefix
23        # to where lldb's python libraries will be installed.
24        #
25        # The way we're going to compute this is to take the relative path from
26        # PYTHON'S prefix to where python libraries are supposed to be
27        # installed.
28        #
29        # The result is if LLDB and python are give the same prefix, then
30        # lldb's python lib will be put in the correct place for python to find it.
31        # If not, you'll have to use lldb -P or lldb -print-script-interpreter-info
32        # to figure out where it is.
33        try:
34            print(relpath_nodots(sysconfig.get_path("platlib"), sys.prefix))
35        except ValueError:
36            # Try to fall back to something reasonable if sysconfig's platlib
37            # is outside of sys.prefix
38            if os.name == 'posix':
39                print('lib/python%d.%d/site-packages' % sys.version_info[:2])
40            elif os.name == 'nt':
41                print('Lib\\site-packages')
42            else:
43                raise
44    elif args.variable_name == "LLDB_PYTHON_EXE_RELATIVE_PATH":
45        tried = list()
46        exe = sys.executable
47        prefix = os.path.realpath(sys.prefix)
48        while True:
49            try:
50                print(relpath_nodots(exe, prefix))
51                break
52            except ValueError:
53                tried.append(exe)
54                # Retry if the executable is symlinked or similar.
55                # This is roughly equal to os.path.islink, except it also works for junctions on Windows.
56                if os.path.realpath(exe) != exe:
57                    exe = os.path.realpath(exe)
58                    continue
59                else:
60                    print("Could not find a relative path to sys.executable under sys.prefix", file=sys.stderr)
61                    for e in tried:
62                        print("tried:", e, file=sys.stderr)
63                    print("realpath(sys.prefix):", prefix, file=sys.stderr)
64                    print("sys.prefix:", sys.prefix, file=sys.stderr)
65                    sys.exit(1)
66    elif args.variable_name == "LLDB_PYTHON_EXT_SUFFIX":
67        print(sysconfig.get_config_var('EXT_SUFFIX'))
68    else:
69        parser.error(f"unknown variable {args.variable_name}")
70
71if __name__ == '__main__':
72    main()
73