diff --git a/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl b/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl index c79ad6c73928b..ffa305c772e88 100644 --- a/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl +++ b/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl @@ -599,6 +599,7 @@ def _features(cpu, compiler, ctx): ] elif cpu == "x64_windows": return [ + feature(name = "compiler_param_file"), feature(name = "no_legacy_features"), feature( name = "common_flags", @@ -623,12 +624,6 @@ def _features(cpu, compiler, ctx): flag_set( actions = all_compile_actions(), flag_groups = [ - flag_group( - flags = [ - "-B", - "external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py", - ], - ), _nologo(), flag_group( flags = [ diff --git a/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl b/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl index 447e5ba7ec96e..cf2ae1669b2d7 100644 --- a/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl +++ b/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl @@ -193,7 +193,30 @@ def InvokeNvcc(argv, log=False): proc.wait() return proc.returncode +def ExpandParamsFileForArgv(): + new_argv = [] + for arg in sys.argv: + if arg.startswith("@"): + with open(arg.strip("@")) as f: + new_argv.extend([l.strip() for l in f.readlines()]) + else: + new_argv.append(arg) + + sys.argv = new_argv + +def ProcessFlagForCommandFile(flag): + if flag.startswith("/D") or flag.startswith("-D"): + # We need to re-escape /DFOO="BAR" as /DFOO=\"BAR\", so that we get + # `#define FOO "BAR"` after expansion as a string literal define + if flag.endswith('"') and not flag.endswith('\\"'): + flag = '\\"'.join(flag.split('"', 1)) + flag = '\\"'.join(flag.rsplit('"', 1)) + return flag + return flag + + def main(): + ExpandParamsFileForArgv() parser = ArgumentParser() parser.add_argument('-x', nargs=1) parser.add_argument('--cuda_log', action='store_true') @@ -213,7 +236,18 @@ def main(): if not flag.startswith(('--cuda_log')) and not flag.startswith(('-nvcc_options'))] - return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) + output = [flag for flag in cpu_compiler_flags if flag.startswith("/Fo")] + + # Store command line options in a file to avoid hitting the character limit. + if len(output) == 1: + commandfile_path = output[0][3:] + ".msvc_params" + commandfile = open(commandfile_path, "w") + cpu_compiler_flags = [ProcessFlagForCommandFile(flag) for flag in cpu_compiler_flags] + commandfile.write("\n".join(cpu_compiler_flags)) + commandfile.close() + return subprocess.call([CPU_COMPILER, "@" + commandfile_path]) + else: + return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) if __name__ == '__main__': sys.exit(main()) diff --git a/third_party/gpus/cuda_configure.bzl b/third_party/gpus/cuda_configure.bzl index 1f94be8c7e41b..1ce2e9e6fbeb3 100644 --- a/third_party/gpus/cuda_configure.bzl +++ b/third_party/gpus/cuda_configure.bzl @@ -168,7 +168,7 @@ def _get_win_cuda_defines(repository_ctx): ), ) - msvc_cl_path = get_python_bin(repository_ctx) + msvc_cl_path = "windows/msvc_wrapper_for_nvcc.bat" msvc_ml_path = find_msvc_tool(repository_ctx, vc_path, "ml64.exe").replace( "\\", "/", @@ -1301,6 +1301,11 @@ def _create_local_cuda_repository(repository_ctx): tpl_paths["crosstool:clang/bin/crosstool_wrapper_driver_is_not_gcc"], wrapper_defines, ) + repository_ctx.file( + "crosstool/windows/msvc_wrapper_for_nvcc.bat", + content = "@echo OFF\n{} -B external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py %*".format( + get_python_bin(repository_ctx)) + ) repository_ctx.template( "crosstool/windows/msvc_wrapper_for_nvcc.py", tpl_paths["crosstool:windows/msvc_wrapper_for_nvcc.py"], diff --git a/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl b/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl index c79ad6c73928b..ffa305c772e88 100644 --- a/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl +++ b/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl @@ -599,6 +599,7 @@ def _features(cpu, compiler, ctx): ] elif cpu == "x64_windows": return [ + feature(name = "compiler_param_file"), feature(name = "no_legacy_features"), feature( name = "common_flags", @@ -623,12 +624,6 @@ def _features(cpu, compiler, ctx): flag_set( actions = all_compile_actions(), flag_groups = [ - flag_group( - flags = [ - "-B", - "external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py", - ], - ), _nologo(), flag_group( flags = [ diff --git a/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl b/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl index 447e5ba7ec96e..cf2ae1669b2d7 100644 --- a/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl +++ b/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl @@ -193,7 +193,30 @@ def InvokeNvcc(argv, log=False): proc.wait() return proc.returncode +def ExpandParamsFileForArgv(): + new_argv = [] + for arg in sys.argv: + if arg.startswith("@"): + with open(arg.strip("@")) as f: + new_argv.extend([l.strip() for l in f.readlines()]) + else: + new_argv.append(arg) + + sys.argv = new_argv + +def ProcessFlagForCommandFile(flag): + if flag.startswith("/D") or flag.startswith("-D"): + # We need to re-escape /DFOO="BAR" as /DFOO=\"BAR\", so that we get + # `#define FOO "BAR"` after expansion as a string literal define + if flag.endswith('"') and not flag.endswith('\\"'): + flag = '\\"'.join(flag.split('"', 1)) + flag = '\\"'.join(flag.rsplit('"', 1)) + return flag + return flag + + def main(): + ExpandParamsFileForArgv() parser = ArgumentParser() parser.add_argument('-x', nargs=1) parser.add_argument('--cuda_log', action='store_true') @@ -213,7 +236,18 @@ def main(): if not flag.startswith(('--cuda_log')) and not flag.startswith(('-nvcc_options'))] - return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) + output = [flag for flag in cpu_compiler_flags if flag.startswith("/Fo")] + + # Store command line options in a file to avoid hitting the character limit. + if len(output) == 1: + commandfile_path = output[0][3:] + ".msvc_params" + commandfile = open(commandfile_path, "w") + cpu_compiler_flags = [ProcessFlagForCommandFile(flag) for flag in cpu_compiler_flags] + commandfile.write("\n".join(cpu_compiler_flags)) + commandfile.close() + return subprocess.call([CPU_COMPILER, "@" + commandfile_path]) + else: + return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) if __name__ == '__main__': sys.exit(main()) diff --git a/third_party/tsl/third_party/gpus/cuda_configure.bzl b/third_party/tsl/third_party/gpus/cuda_configure.bzl index 1f94be8c7e41b..1ce2e9e6fbeb3 100644 --- a/third_party/tsl/third_party/gpus/cuda_configure.bzl +++ b/third_party/tsl/third_party/gpus/cuda_configure.bzl @@ -168,7 +168,7 @@ def _get_win_cuda_defines(repository_ctx): ), ) - msvc_cl_path = get_python_bin(repository_ctx) + msvc_cl_path = "windows/msvc_wrapper_for_nvcc.bat" msvc_ml_path = find_msvc_tool(repository_ctx, vc_path, "ml64.exe").replace( "\\", "/", @@ -1301,6 +1301,11 @@ def _create_local_cuda_repository(repository_ctx): tpl_paths["crosstool:clang/bin/crosstool_wrapper_driver_is_not_gcc"], wrapper_defines, ) + repository_ctx.file( + "crosstool/windows/msvc_wrapper_for_nvcc.bat", + content = "@echo OFF\n{} -B external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py %*".format( + get_python_bin(repository_ctx)) + ) repository_ctx.template( "crosstool/windows/msvc_wrapper_for_nvcc.py", tpl_paths["crosstool:windows/msvc_wrapper_for_nvcc.py"],