1#!/usr/bin/env python3 2 3"""Helps manage sysroots.""" 4 5import argparse 6import os 7import subprocess 8import sys 9 10 11def make_fake_sysroot(out_dir): 12 def cmdout(cmd): 13 return subprocess.check_output(cmd).decode(sys.stdout.encoding).strip() 14 15 if sys.platform == "win32": 16 17 def mkjunction(dst, src): 18 subprocess.check_call(["mklink", "/j", dst, src], shell=True) 19 20 os.mkdir(out_dir) 21 p = os.getenv("ProgramFiles(x86)", "C:\\Program Files (x86)") 22 23 winsdk = os.getenv("WindowsSdkDir") 24 if not winsdk: 25 winsdk = os.path.join(p, "Windows Kits", "10") 26 print("%WindowsSdkDir% not set. You might want to run this from") 27 print("a Visual Studio cmd prompt. Defaulting to", winsdk) 28 os.mkdir(os.path.join(out_dir, "Windows Kits")) 29 mkjunction(os.path.join(out_dir, "Windows Kits", "10"), winsdk) 30 31 vswhere = os.path.join(p, "Microsoft Visual Studio", "Installer", "vswhere") 32 vcid = "Microsoft.VisualStudio.Component.VC.Tools.x86.x64" 33 vsinstalldir = cmdout( 34 [ 35 vswhere, 36 "-latest", 37 "-products", 38 "*", 39 "-requires", 40 vcid, 41 "-property", 42 "installationPath", 43 ] 44 ) 45 46 mkjunction(os.path.join(out_dir, "VC"), os.path.join(vsinstalldir, "VC")) 47 # Not all MSVC versions ship the DIA SDK, so the junction destination 48 # might not exist. That's fine. 49 mkjunction( 50 os.path.join(out_dir, "DIA SDK"), os.path.join(vsinstalldir, "DIA SDK") 51 ) 52 elif sys.platform == "darwin": 53 # The SDKs used by default in compiler-rt/cmake/base-config-ix.cmake. 54 # COMPILER_RT_ENABLE_IOS defaults to on. 55 # COMPILER_RT_ENABLE_WATCHOS and COMPILER_RT_ENABLE_TV default to off. 56 # compiler-rt/cmake/config-ix.cmake sets DARWIN_EMBEDDED_PLATFORMS 57 # depending on these. 58 sdks = ["macosx", "iphoneos", "iphonesimulator"] 59 os.mkdir(out_dir) 60 for sdk in sdks: 61 sdkpath = cmdout(["xcrun", "-sdk", sdk, "-show-sdk-path"]) 62 # sdkpath is something like /.../SDKs/MacOSX11.1.sdk, which is a 63 # symlink to MacOSX.sdk in the same directory. Resolve the symlink, 64 # to make the symlink in out_dir less likely to break when the SDK 65 # is updated (which will bump the number on xcrun's output, but not 66 # on the symlink destination). 67 sdkpath = os.path.realpath(sdkpath) 68 os.symlink(sdkpath, os.path.join(out_dir, os.path.basename(sdkpath))) 69 else: 70 os.symlink("/", out_dir) 71 72 print("Done. Pass these flags to cmake:") 73 abs_out_dir = os.path.abspath(out_dir) 74 if sys.platform == "win32": 75 # CMake doesn't like backslashes in commandline args. 76 abs_out_dir = abs_out_dir.replace(os.path.sep, "/") 77 print(" -DLLVM_WINSYSROOT=" + abs_out_dir) 78 elif sys.platform == "darwin": 79 flags = [ 80 "-DCMAKE_OSX_SYSROOT=" + os.path.join(abs_out_dir, "MacOSX.sdk"), 81 # For find_darwin_sdk_dir() in 82 # compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake 83 "-DDARWIN_macosx_CACHED_SYSROOT=" + os.path.join(abs_out_dir, "MacOSX.sdk"), 84 "-DDARWIN_iphoneos_CACHED_SYSROOT=" 85 + os.path.join(abs_out_dir, "iPhoneOS.sdk"), 86 "-DDARWIN_iphonesimulator_CACHED_SYSROOT=" 87 + os.path.join(abs_out_dir, "iPhoneSimulator.sdk"), 88 ] 89 print(" " + " ".join(flags)) 90 else: 91 print(" -DCMAKE_SYSROOT=" + abs_out_dir + " to cmake.") 92 93 94def main(): 95 parser = argparse.ArgumentParser(description=__doc__) 96 97 subparsers = parser.add_subparsers(dest="command", required=True) 98 99 makefake = subparsers.add_parser( 100 "make-fake", help="Create a sysroot that symlinks to local directories." 101 ) 102 makefake.add_argument("--out-dir", required=True) 103 104 args = parser.parse_args() 105 106 assert args.command == "make-fake" 107 make_fake_sysroot(args.out_dir) 108 109 110if __name__ == "__main__": 111 main() 112