#!/usr/bin/env python3 """Helps manage sysroots.""" import argparse import os import subprocess import sys def make_fake_sysroot(out_dir): def cmdout(cmd): return subprocess.check_output(cmd).decode(sys.stdout.encoding).strip() if sys.platform == "win32": def mkjunction(dst, src): subprocess.check_call(["mklink", "/j", dst, src], shell=True) os.mkdir(out_dir) p = os.getenv("ProgramFiles(x86)", "C:\\Program Files (x86)") winsdk = os.getenv("WindowsSdkDir") if not winsdk: winsdk = os.path.join(p, "Windows Kits", "10") print("%WindowsSdkDir% not set. You might want to run this from") print("a Visual Studio cmd prompt. Defaulting to", winsdk) os.mkdir(os.path.join(out_dir, "Windows Kits")) mkjunction(os.path.join(out_dir, "Windows Kits", "10"), winsdk) vswhere = os.path.join(p, "Microsoft Visual Studio", "Installer", "vswhere") vcid = "Microsoft.VisualStudio.Component.VC.Tools.x86.x64" vsinstalldir = cmdout( [ vswhere, "-latest", "-products", "*", "-requires", vcid, "-property", "installationPath", ] ) mkjunction(os.path.join(out_dir, "VC"), os.path.join(vsinstalldir, "VC")) # Not all MSVC versions ship the DIA SDK, so the junction destination # might not exist. That's fine. mkjunction( os.path.join(out_dir, "DIA SDK"), os.path.join(vsinstalldir, "DIA SDK") ) elif sys.platform == "darwin": # The SDKs used by default in compiler-rt/cmake/base-config-ix.cmake. # COMPILER_RT_ENABLE_IOS defaults to on. # COMPILER_RT_ENABLE_WATCHOS and COMPILER_RT_ENABLE_TV default to off. # compiler-rt/cmake/config-ix.cmake sets DARWIN_EMBEDDED_PLATFORMS # depending on these. sdks = ["macosx", "iphoneos", "iphonesimulator"] os.mkdir(out_dir) for sdk in sdks: sdkpath = cmdout(["xcrun", "-sdk", sdk, "-show-sdk-path"]) # sdkpath is something like /.../SDKs/MacOSX11.1.sdk, which is a # symlink to MacOSX.sdk in the same directory. Resolve the symlink, # to make the symlink in out_dir less likely to break when the SDK # is updated (which will bump the number on xcrun's output, but not # on the symlink destination). sdkpath = os.path.realpath(sdkpath) os.symlink(sdkpath, os.path.join(out_dir, os.path.basename(sdkpath))) else: os.symlink("/", out_dir) print("Done. Pass these flags to cmake:") abs_out_dir = os.path.abspath(out_dir) if sys.platform == "win32": # CMake doesn't like backslashes in commandline args. abs_out_dir = abs_out_dir.replace(os.path.sep, "/") print(" -DLLVM_WINSYSROOT=" + abs_out_dir) elif sys.platform == "darwin": flags = [ "-DCMAKE_OSX_SYSROOT=" + os.path.join(abs_out_dir, "MacOSX.sdk"), # For find_darwin_sdk_dir() in # compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake "-DDARWIN_macosx_CACHED_SYSROOT=" + os.path.join(abs_out_dir, "MacOSX.sdk"), "-DDARWIN_iphoneos_CACHED_SYSROOT=" + os.path.join(abs_out_dir, "iPhoneOS.sdk"), "-DDARWIN_iphonesimulator_CACHED_SYSROOT=" + os.path.join(abs_out_dir, "iPhoneSimulator.sdk"), ] print(" " + " ".join(flags)) else: print(" -DCMAKE_SYSROOT=" + abs_out_dir + " to cmake.") def main(): parser = argparse.ArgumentParser(description=__doc__) subparsers = parser.add_subparsers(dest="command", required=True) makefake = subparsers.add_parser( "make-fake", help="Create a sysroot that symlinks to local directories." ) makefake.add_argument("--out-dir", required=True) args = parser.parse_args() assert args.command == "make-fake" make_fake_sysroot(args.out_dir) if __name__ == "__main__": main()