Index: llvm/cmake/modules/HandleLLVMOptions.cmake =================================================================== --- llvm/cmake/modules/HandleLLVMOptions.cmake +++ llvm/cmake/modules/HandleLLVMOptions.cmake @@ -431,6 +431,16 @@ -D_UNICODE ) + # Allow setting clang-cl's /winsysroot flag. + set(LLVM_WINSYSROOT "" CACHE STRING + "If set, argument to clang-cl's /winsysroot") + if (LLVM_WINSYSROOT) + if (NOT CLANG_CL) + message(ERROR "LLVM_WINSYSROOT requires clang-cl") + endif() + append("/winsysroot${LLVM_WINSYSROOT}" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif() + if (LLVM_ENABLE_WERROR) append("/WX" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif (LLVM_ENABLE_WERROR) Index: llvm/utils/gn/build/BUILD.gn =================================================================== --- llvm/utils/gn/build/BUILD.gn +++ llvm/utils/gn/build/BUILD.gn @@ -22,6 +22,9 @@ # The version of host gcc. Ignored if is_clang is true. gcc_version = 9 + + # Path of sysroot to use. + sysroot = "" } assert(!llvm_build_instrumented_coverage || is_clang, @@ -281,6 +284,11 @@ ] } } + if (sysroot != "") { + assert(current_os == "win", "FIXME: Make sysroot work on non-win") + assert(is_clang, "sysroot only works with clang-cl as host compiler") + cflags += [ "/winsysroot" + sysroot ] + } if (use_ubsan) { assert(is_clang && current_os == "linux", Index: llvm/utils/sysroot.py =================================================================== --- /dev/null +++ llvm/utils/sysroot.py @@ -0,0 +1,66 @@ +#!/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': + 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) + + 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']) + + def mkjunction(dst, src): + subprocess.check_call(['mklink', '/j', dst, src], shell=True) + os.mkdir(out_dir) + mkjunction(os.path.join(out_dir, 'VC'), + os.path.join(vsinstalldir, 'VC')) + os.mkdir(os.path.join(out_dir, 'Windows Kits')) + mkjunction(os.path.join(out_dir, 'Windows Kits', '10'), winsdk) + else: + assert False, "FIXME: Implement on non-win" + + print('Done.') + if sys.platform == 'win32': + # CMake doesn't like backslashes in commandline args. + abs_out_dir = os.path.abspath(out_dir).replace(os.path.sep, '/') + print('Pass -DLLVM_WINSYSROOT=' + abs_out_dir + ' to cmake.') + else: + print('Pass -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()