xref: /llvm-project/llvm/utils/sysroot.py (revision b71edfaa4ec3c998aadb35255ce2f60bba2940b0)
144ea794cSNico Weber#!/usr/bin/env python3
244ea794cSNico Weber
344ea794cSNico Weber"""Helps manage sysroots."""
444ea794cSNico Weber
544ea794cSNico Weberimport argparse
644ea794cSNico Weberimport os
744ea794cSNico Weberimport subprocess
844ea794cSNico Weberimport sys
944ea794cSNico Weber
1044ea794cSNico Weber
1144ea794cSNico Weberdef make_fake_sysroot(out_dir):
1244ea794cSNico Weber    def cmdout(cmd):
1344ea794cSNico Weber        return subprocess.check_output(cmd).decode(sys.stdout.encoding).strip()
1444ea794cSNico Weber
15*b71edfaaSTobias Hieta    if sys.platform == "win32":
16*b71edfaaSTobias Hieta
178cfab5deSNico Weber        def mkjunction(dst, src):
18*b71edfaaSTobias Hieta            subprocess.check_call(["mklink", "/j", dst, src], shell=True)
198cfab5deSNico Weber
208cfab5deSNico Weber        os.mkdir(out_dir)
21*b71edfaaSTobias Hieta        p = os.getenv("ProgramFiles(x86)", "C:\\Program Files (x86)")
2244ea794cSNico Weber
23*b71edfaaSTobias Hieta        winsdk = os.getenv("WindowsSdkDir")
2444ea794cSNico Weber        if not winsdk:
25*b71edfaaSTobias Hieta            winsdk = os.path.join(p, "Windows Kits", "10")
26*b71edfaaSTobias Hieta            print("%WindowsSdkDir% not set. You might want to run this from")
27*b71edfaaSTobias Hieta            print("a Visual Studio cmd prompt. Defaulting to", winsdk)
28*b71edfaaSTobias Hieta        os.mkdir(os.path.join(out_dir, "Windows Kits"))
29*b71edfaaSTobias Hieta        mkjunction(os.path.join(out_dir, "Windows Kits", "10"), winsdk)
3044ea794cSNico Weber
31*b71edfaaSTobias Hieta        vswhere = os.path.join(p, "Microsoft Visual Studio", "Installer", "vswhere")
32*b71edfaaSTobias Hieta        vcid = "Microsoft.VisualStudio.Component.VC.Tools.x86.x64"
3344ea794cSNico Weber        vsinstalldir = cmdout(
34*b71edfaaSTobias Hieta            [
35*b71edfaaSTobias Hieta                vswhere,
36*b71edfaaSTobias Hieta                "-latest",
37*b71edfaaSTobias Hieta                "-products",
38*b71edfaaSTobias Hieta                "*",
39*b71edfaaSTobias Hieta                "-requires",
40*b71edfaaSTobias Hieta                vcid,
41*b71edfaaSTobias Hieta                "-property",
42*b71edfaaSTobias Hieta                "installationPath",
43*b71edfaaSTobias Hieta            ]
44*b71edfaaSTobias Hieta        )
4544ea794cSNico Weber
46*b71edfaaSTobias Hieta        mkjunction(os.path.join(out_dir, "VC"), os.path.join(vsinstalldir, "VC"))
478cfab5deSNico Weber        # Not all MSVC versions ship the DIA SDK, so the junction destination
488cfab5deSNico Weber        # might not exist. That's fine.
49*b71edfaaSTobias Hieta        mkjunction(
50*b71edfaaSTobias Hieta            os.path.join(out_dir, "DIA SDK"), os.path.join(vsinstalldir, "DIA SDK")
51*b71edfaaSTobias Hieta        )
52*b71edfaaSTobias Hieta    elif sys.platform == "darwin":
530ec44819SNico Weber        # The SDKs used by default in compiler-rt/cmake/base-config-ix.cmake.
540ec44819SNico Weber        # COMPILER_RT_ENABLE_IOS defaults to on.
550ec44819SNico Weber        # COMPILER_RT_ENABLE_WATCHOS and COMPILER_RT_ENABLE_TV default to off.
560ec44819SNico Weber        # compiler-rt/cmake/config-ix.cmake sets DARWIN_EMBEDDED_PLATFORMS
570ec44819SNico Weber        # depending on these.
58*b71edfaaSTobias Hieta        sdks = ["macosx", "iphoneos", "iphonesimulator"]
590ec44819SNico Weber        os.mkdir(out_dir)
600ec44819SNico Weber        for sdk in sdks:
61*b71edfaaSTobias Hieta            sdkpath = cmdout(["xcrun", "-sdk", sdk, "-show-sdk-path"])
620ec44819SNico Weber            # sdkpath is something like /.../SDKs/MacOSX11.1.sdk, which is a
630ec44819SNico Weber            # symlink to MacOSX.sdk in the same directory. Resolve the symlink,
640ec44819SNico Weber            # to make the symlink in out_dir less likely to break when the SDK
650ec44819SNico Weber            # is updated (which will bump the number on xcrun's output, but not
660ec44819SNico Weber            # on the symlink destination).
670ec44819SNico Weber            sdkpath = os.path.realpath(sdkpath)
680ec44819SNico Weber            os.symlink(sdkpath, os.path.join(out_dir, os.path.basename(sdkpath)))
6944ea794cSNico Weber    else:
70*b71edfaaSTobias Hieta        os.symlink("/", out_dir)
7144ea794cSNico Weber
72*b71edfaaSTobias Hieta    print("Done. Pass these flags to cmake:")
736073f87dSNico Weber    abs_out_dir = os.path.abspath(out_dir)
74*b71edfaaSTobias Hieta    if sys.platform == "win32":
7544ea794cSNico Weber        # CMake doesn't like backslashes in commandline args.
76*b71edfaaSTobias Hieta        abs_out_dir = abs_out_dir.replace(os.path.sep, "/")
77*b71edfaaSTobias Hieta        print("  -DLLVM_WINSYSROOT=" + abs_out_dir)
78*b71edfaaSTobias Hieta    elif sys.platform == "darwin":
790ec44819SNico Weber        flags = [
80*b71edfaaSTobias Hieta            "-DCMAKE_OSX_SYSROOT=" + os.path.join(abs_out_dir, "MacOSX.sdk"),
810ec44819SNico Weber            # For find_darwin_sdk_dir() in
820ec44819SNico Weber            # compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake
83*b71edfaaSTobias Hieta            "-DDARWIN_macosx_CACHED_SYSROOT=" + os.path.join(abs_out_dir, "MacOSX.sdk"),
84*b71edfaaSTobias Hieta            "-DDARWIN_iphoneos_CACHED_SYSROOT="
85*b71edfaaSTobias Hieta            + os.path.join(abs_out_dir, "iPhoneOS.sdk"),
86*b71edfaaSTobias Hieta            "-DDARWIN_iphonesimulator_CACHED_SYSROOT="
87*b71edfaaSTobias Hieta            + os.path.join(abs_out_dir, "iPhoneSimulator.sdk"),
880ec44819SNico Weber        ]
89*b71edfaaSTobias Hieta        print("  " + " ".join(flags))
9044ea794cSNico Weber    else:
91*b71edfaaSTobias Hieta        print("  -DCMAKE_SYSROOT=" + abs_out_dir + " to cmake.")
9244ea794cSNico Weber
9344ea794cSNico Weber
9444ea794cSNico Weberdef main():
9544ea794cSNico Weber    parser = argparse.ArgumentParser(description=__doc__)
9644ea794cSNico Weber
97*b71edfaaSTobias Hieta    subparsers = parser.add_subparsers(dest="command", required=True)
9844ea794cSNico Weber
99*b71edfaaSTobias Hieta    makefake = subparsers.add_parser(
100*b71edfaaSTobias Hieta        "make-fake", help="Create a sysroot that symlinks to local directories."
101*b71edfaaSTobias Hieta    )
102*b71edfaaSTobias Hieta    makefake.add_argument("--out-dir", required=True)
10344ea794cSNico Weber
10444ea794cSNico Weber    args = parser.parse_args()
10544ea794cSNico Weber
106*b71edfaaSTobias Hieta    assert args.command == "make-fake"
10744ea794cSNico Weber    make_fake_sysroot(args.out_dir)
10844ea794cSNico Weber
10944ea794cSNico Weber
110*b71edfaaSTobias Hietaif __name__ == "__main__":
11144ea794cSNico Weber    main()
112