mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-23 02:00:20 +07:00
116 lines
3.0 KiB
Python
116 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""CGO compiler shim: clang-cl if present, otherwise MSVC cl with GCC-flag filtering."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def _vs_install() -> str | None:
|
|
pf = os.environ.get("ProgramFiles(x86)", r"C:\Program Files (x86)")
|
|
vswhere = os.path.join(pf, "Microsoft Visual Studio", "Installer", "vswhere.exe")
|
|
if not os.path.isfile(vswhere):
|
|
return None
|
|
r = subprocess.run(
|
|
[vswhere, "-latest", "-products", "*", "-property", "installationPath"],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
if r.returncode != 0 or not r.stdout.strip():
|
|
return None
|
|
return r.stdout.strip().splitlines()[0]
|
|
|
|
|
|
def _find_clang_cl() -> str | None:
|
|
install = _vs_install()
|
|
if not install:
|
|
return None
|
|
llvm = os.path.join(install, "VC", "Tools", "Llvm")
|
|
if not os.path.isdir(llvm):
|
|
return None
|
|
preferred: list[str] = []
|
|
fallback: list[str] = []
|
|
for root, _, files in os.walk(llvm):
|
|
if "clang-cl.exe" not in files:
|
|
continue
|
|
path = os.path.join(root, "clang-cl.exe")
|
|
if "arm64" in root.lower():
|
|
preferred.append(path)
|
|
else:
|
|
fallback.append(path)
|
|
if preferred:
|
|
return preferred[0]
|
|
if fallback:
|
|
return fallback[0]
|
|
direct = os.path.join(llvm, "bin", "clang-cl.exe")
|
|
return direct if os.path.isfile(direct) else None
|
|
|
|
|
|
def _gcc_args_to_msvc(args: list[str]) -> list[str]:
|
|
out: list[str] = []
|
|
i = 0
|
|
while i < len(args):
|
|
a = args[i]
|
|
if a == "-x" and i + 1 < len(args):
|
|
i += 2
|
|
continue
|
|
if a == "-o" and i + 1 < len(args):
|
|
obj = args[i + 1]
|
|
if obj.endswith((".o", ".obj")):
|
|
out.append("/Fo" + obj)
|
|
else:
|
|
out.append("/Fe" + obj)
|
|
i += 2
|
|
continue
|
|
if a.startswith("-W") or a.startswith("-f") or a.startswith("-d"):
|
|
i += 1
|
|
continue
|
|
if a.startswith("-m") or a.startswith("-std=") or a in ("-pthread",):
|
|
i += 1
|
|
continue
|
|
if a == "-O2":
|
|
out.append("/O2")
|
|
i += 1
|
|
continue
|
|
if a == "-O0":
|
|
out.append("/Od")
|
|
i += 1
|
|
continue
|
|
if a == "-g":
|
|
out.append("/Zi")
|
|
i += 1
|
|
continue
|
|
if a == "-c":
|
|
out.append("/c")
|
|
i += 1
|
|
continue
|
|
if a.startswith("-D"):
|
|
out.append("/D" + a[2:])
|
|
i += 1
|
|
continue
|
|
if a.startswith("-I"):
|
|
out.append("/I" + a[2:])
|
|
i += 1
|
|
continue
|
|
if not a.startswith("-"):
|
|
out.append(a)
|
|
i += 1
|
|
return out
|
|
|
|
|
|
def main() -> int:
|
|
args = sys.argv[1:]
|
|
clang = _find_clang_cl()
|
|
if clang:
|
|
return subprocess.call([clang, *args])
|
|
|
|
msvc = _gcc_args_to_msvc(args)
|
|
return subprocess.call(["cl", *msvc])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|