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