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