aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/cpp
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2018-07-06 07:00:14 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-06 07:02:00 -0700
commit5947f474e152f7b1f447ef9c9392cd632c1fdd81 (patch)
tree4a48790ddb7cc5b5a11377d63af499cd463409b1 /tools/cpp
parente4809f2f8b6a3d2a71ffc64aca6ff43fb858cc87 (diff)
Windows, CROSSTOOL: Remove MSVC wrapper scripts from Bazel completely
The only reason that those python wrapper scripts still exists is for TensorFlow's Windows GPU build. As we will create a custom GPU CROSSTOOL in TF repo, we can finally remove wrapper scripts from Bazel. Closes #5526. RELNOTES: Python wrapper scripts for MSVC are removed. PiperOrigin-RevId: 203472223
Diffstat (limited to 'tools/cpp')
-rw-r--r--tools/cpp/BUILD.static.windows19
-rw-r--r--tools/cpp/CROSSTOOL.tpl19
-rw-r--r--tools/cpp/cc_configure.bzl5
-rw-r--r--tools/cpp/windows_cc_configure.bzl124
-rw-r--r--tools/cpp/wrapper/bin/call_python.bat.tpl25
-rw-r--r--tools/cpp/wrapper/bin/msvc_cl.bat17
-rw-r--r--tools/cpp/wrapper/bin/msvc_link.bat17
-rw-r--r--tools/cpp/wrapper/bin/msvc_nop.bat17
-rw-r--r--tools/cpp/wrapper/bin/pydir/msvc_cl.py113
-rw-r--r--tools/cpp/wrapper/bin/pydir/msvc_link.py122
-rw-r--r--tools/cpp/wrapper/bin/pydir/msvc_tools.py.tpl465
11 files changed, 2 insertions, 941 deletions
diff --git a/tools/cpp/BUILD.static.windows b/tools/cpp/BUILD.static.windows
index dd3ce9fe00..b6af344738 100644
--- a/tools/cpp/BUILD.static.windows
+++ b/tools/cpp/BUILD.static.windows
@@ -100,8 +100,8 @@ toolchain(
cc_toolchain(
name = "cc-compiler-x64_windows",
- all_files = ":every-file-x64_windows",
- compiler_files = ":compile-x64_windows",
+ all_files = ":empty",
+ compiler_files = ":empty",
cpu = "x64_windows",
dwp_files = ":empty",
dynamic_runtime_libs = [":empty"],
@@ -153,21 +153,6 @@ toolchain(
)
filegroup(
- name = "every-file-x64_windows",
- srcs = [
- ":compile-x64_windows",
- ],
-)
-
-filegroup(
- name = "compile-x64_windows",
- srcs = glob([
- "wrapper/bin/msvc_*",
- "wrapper/bin/pydir/msvc*",
- ]),
-)
-
-filegroup(
name = "link_dynamic_library",
srcs = ["link_dynamic_library.sh"],
)
diff --git a/tools/cpp/CROSSTOOL.tpl b/tools/cpp/CROSSTOOL.tpl
index acc1d5fc72..fa6da1e342 100644
--- a/tools/cpp/CROSSTOOL.tpl
+++ b/tools/cpp/CROSSTOOL.tpl
@@ -396,7 +396,6 @@ toolchain {
implies: 'linker_subsystem_flag'
implies: 'linker_param_file'
implies: 'msvc_env'
- implies: 'use_linker'
implies: 'no_stripping'
}
@@ -416,7 +415,6 @@ toolchain {
implies: 'linker_subsystem_flag'
implies: 'linker_param_file'
implies: 'msvc_env'
- implies: 'use_linker'
implies: 'no_stripping'
implies: 'has_configured_linker_path'
implies: 'def_file'
@@ -438,7 +436,6 @@ toolchain {
implies: 'linker_subsystem_flag'
implies: 'linker_param_file'
implies: 'msvc_env'
- implies: 'use_linker'
implies: 'no_stripping'
implies: 'has_configured_linker_path'
implies: 'def_file'
@@ -514,19 +511,6 @@ toolchain {
}
feature {
- name: "use_linker"
- env_set {
- action: "c++-link-executable"
- action: "c++-link-dynamic-library"
- action: "c++-link-nodeps-dynamic-library"
- env_entry {
- key: "USE_LINKER"
- value: "1"
- }
- }
- }
-
- feature {
name: 'include_paths'
flag_set {
action: "assemble"
@@ -1093,7 +1077,4 @@ toolchain {
}
linking_mode_flags { mode: DYNAMIC }
-
-%{compilation_mode_content}
-
}
diff --git a/tools/cpp/cc_configure.bzl b/tools/cpp/cc_configure.bzl
index 57954f6f71..cf4c389bca 100644
--- a/tools/cpp/cc_configure.bzl
+++ b/tools/cpp/cc_configure.bzl
@@ -76,14 +76,9 @@ cc_autoconf = repository_rule(
"CC_CONFIGURE_DEBUG",
"CC_TOOLCHAIN_NAME",
"CPLUS_INCLUDE_PATH",
- "CUDA_COMPUTE_CAPABILITIES",
- "CUDA_PATH",
"GCOV",
"HOMEBREW_RUBY_PATH",
- "NO_WHOLE_ARCHIVE_OPTION",
"SYSTEMROOT",
- "USE_DYNAMIC_CRT",
- "USE_MSVC_WRAPPER",
"VS90COMNTOOLS",
"VS100COMNTOOLS",
"VS110COMNTOOLS",
diff --git a/tools/cpp/windows_cc_configure.bzl b/tools/cpp/windows_cc_configure.bzl
index 149eb3947b..a85ef5877e 100644
--- a/tools/cpp/windows_cc_configure.bzl
+++ b/tools/cpp/windows_cc_configure.bzl
@@ -80,27 +80,6 @@ def _get_system_root(repository_ctx):
auto_configure_warning("SYSTEMROOT is not set, using default SYSTEMROOT=C:\\Windows")
return "C:\\Windows"
-def _find_cuda(repository_ctx):
- """Find out if and where cuda is installed. Doesn't %-escape the result."""
- if "CUDA_PATH" in repository_ctx.os.environ:
- return repository_ctx.os.environ["CUDA_PATH"]
- nvcc = which(repository_ctx, "nvcc.exe")
- if nvcc:
- return nvcc[:-len("/bin/nvcc.exe")]
- return None
-
-def _find_python(repository_ctx):
- """Find where is python on Windows. Doesn't %-escape the result."""
- if "BAZEL_PYTHON" in repository_ctx.os.environ:
- python_binary = repository_ctx.os.environ["BAZEL_PYTHON"]
- if not python_binary.endswith(".exe"):
- python_binary = python_binary + ".exe"
- return python_binary
- auto_configure_warning("'BAZEL_PYTHON' is not set, start looking for python in PATH.")
- python_binary = which_cmd(repository_ctx, "python.exe")
- auto_configure_warning("Python found at %s" % python_binary)
- return python_binary
-
def _add_system_root(repository_ctx, env):
"""Running VCVARSALL.BAT and VCVARSQUERYREGISTRY.BAT need %SYSTEMROOT%\\\\system32 in PATH."""
if "PATH" not in env:
@@ -269,62 +248,12 @@ def _find_missing_vc_tools(repository_ctx, vc_path):
return missing_tools
-def _is_support_whole_archive(repository_ctx, vc_path):
- """Run MSVC linker alone to see if it supports /WHOLEARCHIVE."""
- env = repository_ctx.os.environ
- if "NO_WHOLE_ARCHIVE_OPTION" in env and env["NO_WHOLE_ARCHIVE_OPTION"] == "1":
- return False
- linker = find_msvc_tool(repository_ctx, vc_path, "link.exe")
- result = execute(repository_ctx, [linker], expect_failure = True)
- return result.find("/WHOLEARCHIVE") != -1
-
def _is_support_debug_fastlink(repository_ctx, vc_path):
"""Run MSVC linker alone to see if it supports /DEBUG:FASTLINK."""
linker = find_msvc_tool(repository_ctx, vc_path, "link.exe")
result = execute(repository_ctx, [linker], expect_failure = True)
return result.find("/DEBUG[:{FASTLINK|FULL|NONE}]") != -1
-def _is_use_msvc_wrapper(repository_ctx):
- """Returns True if USE_MSVC_WRAPPER is set to 1."""
- env = repository_ctx.os.environ
- return "USE_MSVC_WRAPPER" in env and env["USE_MSVC_WRAPPER"] == "1"
-
-def _get_compilation_mode_content():
- """Return the content for adding flags for different compilation modes when using MSVC wrapper."""
- return "\n".join([
- " compilation_mode_flags {",
- " mode: DBG",
- " compiler_flag: '-Xcompilation-mode=dbg'",
- " linker_flag: '-Xcompilation-mode=dbg'",
- " }",
- " compilation_mode_flags {",
- " mode: FASTBUILD",
- " compiler_flag: '-Xcompilation-mode=fastbuild'",
- " linker_flag: '-Xcompilation-mode=fastbuild'",
- " }",
- " compilation_mode_flags {",
- " mode: OPT",
- " compiler_flag: '-Xcompilation-mode=opt'",
- " linker_flag: '-Xcompilation-mode=opt'",
- " }",
- ])
-
-def _escaped_cuda_compute_capabilities(repository_ctx):
- """Returns a %-escaped list of strings representing cuda compute capabilities."""
-
- if "CUDA_COMPUTE_CAPABILITIES" not in repository_ctx.os.environ:
- return ["3.5", "5.2"]
- capabilities_str = escape_string(repository_ctx.os.environ["CUDA_COMPUTE_CAPABILITIES"])
- capabilities = capabilities_str.split(",")
- for capability in capabilities:
- # Workaround for Skylark's lack of support for regex. This check should
- # be equivalent to checking:
- # if re.match("[0-9]+.[0-9]+", capability) == None:
- parts = capability.split(".")
- if len(parts) != 2 or not parts[0].isdigit() or not parts[1].isdigit():
- auto_configure_fail("Invalid compute capability: %s" % capability)
- return capabilities
-
def configure_windows_toolchain(repository_ctx):
"""Configure C++ toolchain on Windows."""
paths = resolve_labels(repository_ctx, [
@@ -332,8 +261,6 @@ def configure_windows_toolchain(repository_ctx):
"@bazel_tools//tools/cpp:CROSSTOOL",
"@bazel_tools//tools/cpp:CROSSTOOL.tpl",
"@bazel_tools//tools/cpp:vc_installation_error.bat.tpl",
- "@bazel_tools//tools/cpp:wrapper/bin/call_python.bat.tpl",
- "@bazel_tools//tools/cpp:wrapper/bin/pydir/msvc_tools.py.tpl",
])
repository_ctx.symlink(paths["@bazel_tools//tools/cpp:BUILD.static.windows"], "BUILD")
@@ -404,56 +331,6 @@ def configure_windows_toolchain(repository_ctx):
msvc_link_path = find_msvc_tool(repository_ctx, vc_path, "link.exe").replace("\\", "/")
msvc_lib_path = find_msvc_tool(repository_ctx, vc_path, "lib.exe").replace("\\", "/")
escaped_cxx_include_directories = []
- compilation_mode_content = ""
-
- if _is_use_msvc_wrapper(repository_ctx):
- if _is_support_whole_archive(repository_ctx, vc_path):
- support_whole_archive = "True"
- else:
- support_whole_archive = "False"
- nvcc_tmp_dir_name = escaped_tmp_dir + "\\\\nvcc_inter_files_tmp_dir"
-
- # Make sure nvcc.exe is in PATH
- cuda_path = _find_cuda(repository_ctx)
- if cuda_path:
- escaped_paths = escape_string(cuda_path.replace("\\", "\\\\") + "/bin;") + escaped_paths
- escaped_compute_capabilities = _escaped_cuda_compute_capabilities(repository_ctx)
- repository_ctx.template(
- "wrapper/bin/pydir/msvc_tools.py",
- paths["@bazel_tools//tools/cpp:wrapper/bin/pydir/msvc_tools.py.tpl"],
- {
- "%{lib_tool}": escape_string(msvc_lib_path),
- "%{support_whole_archive}": support_whole_archive,
- "%{cuda_compute_capabilities}": ", ".join(
- ["\"%s\"" % c for c in escaped_compute_capabilities],
- ),
- "%{nvcc_tmp_dir_name}": nvcc_tmp_dir_name,
- },
- )
-
- # nvcc will generate some source files under %{nvcc_tmp_dir_name}
- # The generated files are guranteed to have unique name, so they can share the same tmp directory
- escaped_cxx_include_directories += ["cxx_builtin_include_directory: \"%s\"" % nvcc_tmp_dir_name]
- msvc_wrapper = repository_ctx.path(
- paths["@bazel_tools//tools/cpp:CROSSTOOL"],
- ).dirname.get_child(
- "wrapper",
- ).get_child("bin")
- for f in ["msvc_cl.bat", "msvc_link.bat", "msvc_nop.bat"]:
- repository_ctx.symlink(msvc_wrapper.get_child(f), "wrapper/bin/" + f)
- msvc_wrapper = msvc_wrapper.get_child("pydir")
- for f in ["msvc_cl.py", "msvc_link.py"]:
- repository_ctx.symlink(msvc_wrapper.get_child(f), "wrapper/bin/pydir/" + f)
- python_binary = _find_python(repository_ctx)
- repository_ctx.template(
- "wrapper/bin/call_python.bat",
- paths["@bazel_tools//tools/cpp:wrapper/bin/call_python.bat.tpl"],
- {"%{python_binary}": escape_string(python_binary)},
- )
- msvc_cl_path = "wrapper/bin/msvc_cl.bat"
- msvc_link_path = "wrapper/bin/msvc_link.bat"
- msvc_lib_path = "wrapper/bin/msvc_link.bat"
- compilation_mode_content = _get_compilation_mode_content()
for path in escaped_include_paths.split(";"):
if path:
@@ -478,7 +355,6 @@ def configure_windows_toolchain(repository_ctx):
"%{msvc_lib_path}": msvc_lib_path,
"%{dbg_mode_debug}": "/DEBUG:FULL" if support_debug_fastlink else "/DEBUG",
"%{fastbuild_mode_debug}": "/DEBUG:FASTLINK" if support_debug_fastlink else "/DEBUG",
- "%{compilation_mode_content}": compilation_mode_content,
"%{content}": _get_escaped_windows_msys_crosstool_content(repository_ctx),
"%{msys_x64_mingw_content}": _get_escaped_windows_msys_crosstool_content(repository_ctx, use_mingw = True),
"%{opt_content}": "",
diff --git a/tools/cpp/wrapper/bin/call_python.bat.tpl b/tools/cpp/wrapper/bin/call_python.bat.tpl
deleted file mode 100644
index 1beb42698a..0000000000
--- a/tools/cpp/wrapper/bin/call_python.bat.tpl
+++ /dev/null
@@ -1,25 +0,0 @@
-:: Copyright 2016 The Bazel Authors. All rights reserved.
-::
-:: Licensed under the Apache License, Version 2.0 (the "License");
-:: you may not use this file except in compliance with the License.
-:: You may obtain a copy of the License at
-::
-:: http://www.apache.org/licenses/LICENSE-2.0
-::
-:: Unless required by applicable law or agreed to in writing, software
-:: distributed under the License is distributed on an "AS IS" BASIS,
-:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-:: See the License for the specific language governing permissions and
-:: limitations under the License.
-
-:: Invoke the python script under pydir with the same basename
-@echo OFF
-set arg0=%~1
-for %%F in ("%arg0%") do set DRIVER_BIN=%%~dpF
-
-for /F "delims=" %%i in ("%arg0%") do set TOOLNAME=%%~ni
-
-set PYDIR=%DRIVER_BIN%pydir
-
-if not defined MSVCPYTHON set MSVCPYTHON="%{python_binary}"
-%MSVCPYTHON% -B "%PYDIR%\%TOOLNAME%.py" %*
diff --git a/tools/cpp/wrapper/bin/msvc_cl.bat b/tools/cpp/wrapper/bin/msvc_cl.bat
deleted file mode 100644
index f32dd44871..0000000000
--- a/tools/cpp/wrapper/bin/msvc_cl.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-:: Copyright 2016 The Bazel Authors. All rights reserved.
-::
-:: Licensed under the Apache License, Version 2.0 (the "License");
-:: you may not use this file except in compliance with the License.
-:: You may obtain a copy of the License at
-::
-:: http://www.apache.org/licenses/LICENSE-2.0
-::
-:: Unless required by applicable law or agreed to in writing, software
-:: distributed under the License is distributed on an "AS IS" BASIS,
-:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-:: See the License for the specific language governing permissions and
-:: limitations under the License.
-
-:: Invoke the python script under pydir with the same basename
-@echo OFF
-external\local_config_cc\wrapper\bin\call_python.bat %0 %*
diff --git a/tools/cpp/wrapper/bin/msvc_link.bat b/tools/cpp/wrapper/bin/msvc_link.bat
deleted file mode 100644
index f32dd44871..0000000000
--- a/tools/cpp/wrapper/bin/msvc_link.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-:: Copyright 2016 The Bazel Authors. All rights reserved.
-::
-:: Licensed under the Apache License, Version 2.0 (the "License");
-:: you may not use this file except in compliance with the License.
-:: You may obtain a copy of the License at
-::
-:: http://www.apache.org/licenses/LICENSE-2.0
-::
-:: Unless required by applicable law or agreed to in writing, software
-:: distributed under the License is distributed on an "AS IS" BASIS,
-:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-:: See the License for the specific language governing permissions and
-:: limitations under the License.
-
-:: Invoke the python script under pydir with the same basename
-@echo OFF
-external\local_config_cc\wrapper\bin\call_python.bat %0 %*
diff --git a/tools/cpp/wrapper/bin/msvc_nop.bat b/tools/cpp/wrapper/bin/msvc_nop.bat
deleted file mode 100644
index b422585831..0000000000
--- a/tools/cpp/wrapper/bin/msvc_nop.bat
+++ /dev/null
@@ -1,17 +0,0 @@
-:: Copyright 2016 The Bazel Authors. All rights reserved.
-::
-:: Licensed under the Apache License, Version 2.0 (the "License");
-:: you may not use this file except in compliance with the License.
-:: You may obtain a copy of the License at
-::
-:: http://www.apache.org/licenses/LICENSE-2.0
-::
-:: Unless required by applicable law or agreed to in writing, software
-:: distributed under the License is distributed on an "AS IS" BASIS,
-:: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-:: See the License for the specific language governing permissions and
-:: limitations under the License.
-
-:: Invoke the python script under pydir with the same basename
-@echo OFF
-echo IGNORING: %0 %*
diff --git a/tools/cpp/wrapper/bin/pydir/msvc_cl.py b/tools/cpp/wrapper/bin/pydir/msvc_cl.py
deleted file mode 100644
index c148fdd220..0000000000
--- a/tools/cpp/wrapper/bin/pydir/msvc_cl.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# pylint: disable=g-bad-file-header
-# Copyright 2016 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""Wrapper script for executing the Microsoft Compiler."""
-import os
-import sys
-import msvc_link
-import msvc_tools
-
-SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-sys.path.append(SCRIPT_DIR)
-
-GCCPATTERNS = [
- ('-I(.+)', ['/I$0']),
- ('-m(32|64)', ['$TARGET_ARCH']),
- ('-Xcompilation-mode=(dbg|fastbuild|opt)', ['$COMPILATION_MODE']),
- ('-msse', ['/arch:SSE']),
- ('-msse2', ['/arch:SSE2']),
- ('-D(.+)', ['/D$0']),
- ('-U(.+)', ['/U$0']),
- ('-E', ['/E']),
- ('-O0', ['/Od']),
- ('-Os', ['/O1']),
- ('-O2', ['/O2']),
- ('-g0', []),
- ('-g', ['$DEBUG_RT']),
- ('-fexceptions', ['/U_HAS_EXCEPTIONS', '/D_HAS_EXCEPTIONS=1', '/EHsc']),
- ('-fomit-frame-pointer', ['/Oy']),
- ('-fno-rtti', ['/GR-']),
- ('-frtti', ['/GR']),
- ('-fPIC', []),
-
- # This is unneeded for Windows.
- (('-include', '(.+)'), ['/FI$PATH0']),
- ('-w', ['/w']),
- ('-Wall', ['/Wall']),
- ('-Wsign-compare', ['/we4018']),
- ('-Wno-sign-compare', ['/wd4018']),
- ('-Wconversion', ['/we4244', '/we4267']),
- ('-Wno-conversion', ['/wd4244', '/wd4267']),
- ('-Wno-sign-conversion', []),
- ('-Wno-implicit-fallthrough', []),
- ('-Wno-implicit-function-declaration', ['/wd4013']),
- ('-Wimplicit-function-declaration', ['/we4013']),
- ('-Wcovered-switch-default', ['/we4062']),
- ('-Wno-covered-switch-default', ['/wd4062']),
- ('-Wno-error', []),
- ('-Wno-invalid-offsetof', []),
- ('-Wno-overloaded-virtual', []),
- ('-Wno-reorder', []),
- ('-Wno-string-plus-int', []),
- ('-Wl,S', []), # Stripping is unnecessary since msvc uses pdb files.
- ('-Wl,-rpath(.+)', []),
- ('-B(.+)', []),
- ('-static', []),
- ('-shared', ['/DLL']),
- ('-std=(.+)', []),
-]
-
-
-def _IsLink():
- """Determines whether we need to link rather than compile.
-
- Returns:
- True if USE_LINKER is set to 1.
- """
- return 'USE_LINKER' in os.environ and os.environ['USE_LINKER'] == '1'
-
-
-class MsvcCompiler(msvc_tools.WindowsRunner):
- """Driver for the Microsoft compiler."""
-
- def Run(self, argv):
- """Runs the compiler using the passed clang/gcc style argument list.
-
- Args:
- argv: List of arguments
-
- Returns:
- The return code of the compilation.
-
- Raises:
- ValueError: if target architecture isn't specified
- """
- parser = msvc_tools.ArgParser(self, argv, GCCPATTERNS)
-
- compiler = 'cl'
- if parser.is_cuda_compilation:
- compiler = 'nvcc'
- return self.RunBinary(compiler, parser.options, parser)
-
-
-def main(argv):
- # If we are supposed to link create a static library.
- if _IsLink():
- return msvc_link.main(argv)
- else:
- return MsvcCompiler().Run(argv[1:])
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:])) # need to skip the first argument
diff --git a/tools/cpp/wrapper/bin/pydir/msvc_link.py b/tools/cpp/wrapper/bin/pydir/msvc_link.py
deleted file mode 100644
index 28a58f727f..0000000000
--- a/tools/cpp/wrapper/bin/pydir/msvc_link.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# pylint: disable=g-bad-file-header
-# Copyright 2016 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""Wrapper script for executing the Microsoft Linker."""
-
-import os
-import re
-import sys
-import msvc_tools
-
-SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-
-sys.path.append(SCRIPT_DIR)
-
-LINKPATTERNS = [
- ('-m(32|64)', ['$TARGET_ARCH']),
- ('-Xcompilation-mode=(dbg|fastbuild|opt)', ['$COMPILATION_MODE']),
- (('rcs.*', '(.+)'), ['/OUT:"$PATH0"']),
- (('-o', '(.+)'), ['/OUT:"$PATH0"']),
- ('-B(.+)', []),
- ('-lpthread', []),
- ('-L(.+)', ['/LIBPATH:$PATH0']),
- ('-static', []),
- ('-shared', ['/DLL']),
- ('-no-whole-archive', []),
- ('-rdynamic', []),
- (r'-Wl,(.+)\.lib', ['$0.lib']),
- (r'-DEFAULTLIB:(.+)', ['/DEFAULTLIB:$0']),
- ('-Wl,@(.+)', ['$LOAD_PARAMS0']),
- ('@(.+)', ['$LOAD_PARAMS0']),
- ('-Wl,-rpath(.+)', []),
- ('-Wl,-S', []), # Debug symbols are in pdb files.
- ('-Wl,/SUBSYSTEM:(WINDOWS|CONSOLE)', ['/SUBSYSTEM:$0']),
- (r'/WHOLEARCHIVE:(.+)\.lib', ['$0.lib']),
-]
-
-
-class MsvcLinker(msvc_tools.WindowsRunner):
- """Driver for the Microsoft linker."""
-
- def Run(self, argv):
- """Runs the linker using the passed clang/gcc style argument list.
-
- Args:
- argv: List of arguments
-
- Returns:
- The return code of the link.
-
- Raises:
- ValueError: if target architecture or compile mode isn't specified
- """
- # For now assume we are building a library.
- tool = 'lib'
- default_args = []
-
- # Build argument list.
- parser = msvc_tools.ArgParser(self, argv, LINKPATTERNS)
-
- # Preprocessing arguments for linking whole archive libraries
- parser.WholeArchivePreprocess()
-
- # Find the output file name.
- name = ''
- for arg in parser.options:
- if '/OUT:' in arg:
- name = re.sub(r'^"|"$', '', arg[5:])
- if not name:
- raise msvc_tools.Error('No output file name specified!')
- # Check if the library is empty, which is what happens when we create header
- # or intermediate link-only libraries.
- if (len(parser.options) == 2 and parser.options[0].startswith('/OUT') and
- parser.options[1].startswith('/M')):
- # Just "touch" the library to create the file.
- with open(name, 'w'):
- os.utime(name, None)
- else:
- # If the output name ends in .lo, or .a, it is a library, otherwise
- # we need to use link to create an executable.
- if os.path.splitext(name)[1] not in ['.a', '.lo']:
- tool = 'link'
-
- # If there is no .o on the command line, then we need to add the
- # run-time library for the target. Without this the linker gives a
- # LNK4001 error and cannot find an entry point.
- for arg in parser.options:
- if arg.endswith('.o'):
- break
- else:
- if not parser.compilation_mode:
- raise ValueError('Must specify compilation mode '
- '(-Xcompilation-mode={dbg,fastbuild,opt})')
-
- rtlib = 'libcmt%s.lib'
- # attempt to choose the right runtime library if we can
- for opt in reversed(parser.options):
- if opt in ['/MT', '/MTd']:
- rtlib = 'msvcrt%s.lib'
- break
- default_args.insert(0, rtlib %
- ('d' if parser.compilation_mode == 'dbg' else ''))
-
- return self.RunBinary(tool, default_args + parser.options, parser)
-
-
-def main(argv):
- return MsvcLinker().Run(argv[1:])
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:])) # need to skip the first argument
diff --git a/tools/cpp/wrapper/bin/pydir/msvc_tools.py.tpl b/tools/cpp/wrapper/bin/pydir/msvc_tools.py.tpl
deleted file mode 100644
index 01b4bb6738..0000000000
--- a/tools/cpp/wrapper/bin/pydir/msvc_tools.py.tpl
+++ /dev/null
@@ -1,465 +0,0 @@
-# pylint: disable=g-bad-file-header
-# pylint: disable=cell-var-from-loop
-# Copyright 2016 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""Tools for working with the Microsoft Visual C++ toolchain."""
-
-from argparse import ArgumentParser
-import ntpath
-import os
-import re
-import subprocess
-import sys
-
-MAX_PATH = 260 # The maximum number of characters in a Windows path.
-MAX_OPTION_LENGTH = 10 # The maximum length of a compiler/linker option.
-MAX_DRIVE_LENGTH = 3 # The maximum length of a drive.
-MAX_PATH_ADJUSTED = MAX_PATH - MAX_OPTION_LENGTH - MAX_DRIVE_LENGTH
-ASSEMBLY_AS_C_SOURCE = '/Tc'
-LIB_SUFFIX = '.lib'
-LIB_TOOL = "%{lib_tool}"
-NVCC_TEMP_DIR = "%{nvcc_tmp_dir_name}"
-supported_cuda_compute_capabilities = [ %{cuda_compute_capabilities} ]
-
-class Error(Exception):
- """Base class for all script-specific errors."""
- pass
-
-def Log(s):
- """Print log messages."""
- print('msvc_tools.py: {0}'.format(s))
-
-class ArgParser(object):
- """Class that parses gcc/clang-style options for a Windows.
-
- The particular substitutions that are needed are passed to the object.
- """
-
- def __init__(self, driver, argv, substitutions):
- self.driver = driver
- self.substitutions = substitutions
- self.options = []
- self.leftover = []
- self.target_arch = None
- self.compilation_mode = None
- self.deps_file = None
- self.output_file = None
- self.params_file = None
- self.support_whole_archive = %{support_whole_archive}
- self.global_whole_archive = None
- self.is_cuda_compilation = None
- self.cuda_log = False
- self.enforce_debug_rt = False
- self._ParseArgs(argv)
-
- def ReplaceLibrary(self, arg):
- """Do the actual replacement if necessary."""
- if arg == "/WHOLEARCHIVE":
- return []
- if arg.startswith("/OUT:") or os.path.splitext(arg)[1] not in ['.a', '.lo']:
- return [arg]
- if self.global_whole_archive or arg.startswith("/WHOLEARCHIVE:"):
- if arg.startswith("/WHOLEARCHIVE:"):
- arg = arg[len("/WHOLEARCHIVE:"):]
- output = subprocess.check_output([LIB_TOOL, "/list", arg]).decode("utf-8")
- object_files = []
- for line in output.split("\n"):
- line = line.strip()
- if line.endswith(".o"):
- object_files.append(line)
- return object_files
- return [arg]
-
- def WholeArchivePreprocess(self):
- """Replace library file with object files if /WHOLEARCHIVE is not supported."""
- if self.support_whole_archive:
- return
- options = []
- self.global_whole_archive = "/WHOLEARCHIVE" in self.options
- for arg in self.options:
- options.extend(self.ReplaceLibrary(arg))
- self.options = options
-
- def IsCudaCompilation(self):
- """Check if it's a cuda compilation."""
- parser = ArgumentParser()
- parser.add_argument('-x', nargs=1)
- parser.add_argument('--cuda_log', action='store_true')
- args, leftover = parser.parse_known_args(self.leftover)
- if args.x and args.x[0] == 'cuda':
- if args.cuda_log:
- Log('Using nvcc')
- self.cuda_log = True
- self.leftover = leftover
- return True
- return False
-
- def GetNvccOptions(self):
- """Collect the -nvcc_options values from self.leftover.
-
- Returns:
- The list of options that can be passed directly to nvcc.
- """
-
- parser = ArgumentParser()
- parser.add_argument('-nvcc_options', nargs='*', action='append')
-
- args, leftover = parser.parse_known_args(self.leftover)
-
- if args.nvcc_options:
- self.leftover = leftover
- return ['--'+a for a in sum(args.nvcc_options, [])]
- return []
-
- def GetOptionValue(self, option):
- """Extract the list of values for option from self.options.
-
- Args:
- option: The option whose value to extract, without the leading '/'.
-
- Returns:
- A list of values, either directly following the option,
- (eg., /opt val1 val2) or values collected from multiple occurrences of
- the option (eg., /opt val1 /opt val2).
- """
-
- parser = ArgumentParser(prefix_chars='/')
- parser.add_argument('/' + option, nargs='*', action='append')
- args, leftover = parser.parse_known_args(self.options)
- if args and vars(args)[option]:
- self.options = leftover
- return sum(vars(args)[option], [])
- return []
-
- def GetOptionsForCudaCompilation(self):
- """Get nvcc options with arguments assembled from self.options."""
-
- src_files = [f for f in self.options if
- re.search('\.cpp$|\.cc$|\.c$|\.cxx$|\.C$', f)]
- if len(src_files) == 0:
- raise Error('No source files found for cuda compilation.')
-
- out_file = [ f for f in self.options if f.startswith('/Fo') ]
- if len(out_file) != 1:
- raise Error('Please sepecify exactly one output file for cuda compilation.')
- out = ['-o', out_file[0][len('/Fo'):]]
-
- nvcc_compiler_options = self.GetNvccOptions()
-
- opt_option = self.GetOptionValue('O')
- opt = ['-g', '-G']
- if (len(opt_option) > 0 and opt_option[0] != 'd'):
- opt = ['-O2']
-
- include_options = self.GetOptionValue('I')
- includes = ["-I " + include for include in include_options]
-
- defines = self.GetOptionValue('D')
- defines = ['-D' + define for define in defines]
-
- undefines = self.GetOptionValue('U')
- undefines = ['-U' + define for define in undefines]
-
- # The rest of the unrecongized options should be passed to host compiler
- host_compiler_options = [option for option in self.options if option not in (src_files + out_file)]
-
- m_options = ["-m64"]
-
- nvccopts = ['-D_FORCE_INLINES']
- for capability in supported_cuda_compute_capabilities:
- capability = capability.replace('.', '')
- nvccopts += [r'-gencode=arch=compute_%s,"code=sm_%s,compute_%s"' % (
- capability, capability, capability)]
- nvccopts += nvcc_compiler_options
- nvccopts += undefines
- nvccopts += defines
- nvccopts += m_options
- nvccopts += ['--compiler-options="' + " ".join(host_compiler_options) + '"']
- nvccopts += ['-x', 'cu'] + opt + includes + out + ['-c'] + src_files
- # If we don't specify --keep-dir, nvcc will generate intermediate files under TEMP
- # Put them under NVCC_TEMP_DIR instead, then Bazel can ignore files under NVCC_TEMP_DIR during dependency check
- # http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#options-for-guiding-compiler-driver
- # Different actions are sharing NVCC_TEMP_DIR, so we cannot remove it if the directory already exists.
- if os.path.isfile(NVCC_TEMP_DIR):
- os.remove(NVCC_TEMP_DIR)
- if not os.path.exists(NVCC_TEMP_DIR):
- os.makedirs(NVCC_TEMP_DIR)
- nvccopts += ['--keep', '--keep-dir', NVCC_TEMP_DIR]
-
- if self.cuda_log:
- Log("Running: " + " ".join(["nvcc"] + nvccopts))
-
- self.options = nvccopts
-
- def _MatchOneArg(self, args):
- """Finds a pattern which matches the beginning elements of args.
-
- Args:
- args: A list of arguments to replace.
-
- Returns:
- A tuple of (number of arguments parsed, action, match groups).
- """
- for (regex, action) in self.substitutions:
- if isinstance(regex, str):
- regex = [regex]
- j = 0
- matches = []
- for r in regex:
- if j < len(args):
- match = re.compile('^' + r + '$').match(args[j])
- else:
- match = None
- matches.append(match)
- j += 1
- if None in matches:
- continue
- groups = []
- for m in matches:
- groups.extend(m.groups())
- return (len(regex), action, groups)
- return (0, '', [])
-
- def _ParseArgs(self, argv):
- """Parses argv and replaces its elements using special tokens.
-
- The following is a list of supported tokens. The format is $TOKEN%d, where
- %d is the 0-based group number from regex matches of the pattern.
- $CREATE_PATH%d: Touches a file at the path in the matching token.
- $LOAD_PARAMS%d: Loads an ld-style params file and appends all arguments to
- the current argument list by recursively calling
- _ParseArgs.
- $%d : Numeric token that just replaces the match group with
- the value specified in the match list.
- $PATH%d : Replaces the match with a Windows-normalized version of
- the match; assumes that the match is a path.
- $PATH%d_NO_EXT: Same as $PATH but strips out any file extension.
- $TARGET_ARCH : Set self.target_arch to 'x86' or 'x64' for '-m32' and
- '-m64', respectively.
- $DEBUG_RT : Enforce linkage to debug runtime.
- $COMPILE_OUTPUT%d: Sets the output name of a compilation step.
- $COMPILATION_MODE: Sets self.compilation_mode from the value of a
- '-Xcompilation-mode=' flag.
- $CREATE_PRECOMPILED_HEADER: Informs the system that we are generating a
- precompiled header rather than an object file.
- $GENERATE_DEPS%d: Generates a gcc-style .d file containing dependencies.
-
- Args:
- argv: A list of arguments to replace.
-
- Returns:
- A list of replaced arguments to pass to the target command.
-
- Raises:
- Error: if wrong arguments found
- """
- i = 0
- matched = []
- unmatched = []
- files = []
- while i < len(argv):
- num_matched, action, groups = self._MatchOneArg(argv[i:])
- arg = argv[i]
- if arg.startswith('/Fo') or arg.startswith('/Fa') or arg.startswith(
- '/Fi'):
- self.output_file = arg[3:]
- if num_matched == 0:
- # Strip out any .a's that have 0 size, they are header or intermediate
- # dependency libraries and don't contain any code. 0-length files are
- # considered corrupt by the linker (error LNK1136).
- if (os.path.isfile(arg) and os.path.splitext(arg)[1] == '.a' and
- os.path.getsize(arg) == 0):
- i += 1
- continue
-
- # If the argument is an absolute path, then add it directly.
- if arg[0] == '/':
- self.AddOpt(arg)
- elif os.path.isfile(arg):
- path = self.NormPath(arg)
- ext = os.path.splitext(arg)[1].lower()
- if ext in ['.s']:
- # Treat assembly files as C source files using a special option.
- path = ASSEMBLY_AS_C_SOURCE + path
- # If this is an actual file on disk then just pass it to the tool.
- files.append(path)
- elif not arg.endswith(LIB_SUFFIX):
- # Ignore .lib files.
- unmatched.append(arg)
- i += 1
- continue
- matched += argv[i:i + num_matched]
- # Handle special options.
- for entry in action:
- if entry == '$TARGET_ARCH':
- if arg == '-m32':
- self.target_arch = 'x86'
- elif arg == '-m64':
- self.target_arch = 'x64'
- else:
- raise Error('Unknown target arch flag: %r' % arg)
- continue
-
- if entry == '$COMPILATION_MODE':
- empty, prefix, mode = arg.partition('-Xcompilation-mode=')
- if empty or not prefix or mode not in ['dbg', 'fastbuild', 'opt']:
- raise Error('Invalid compilation mode flag: %r' % arg)
- self.compilation_mode = mode
- continue
-
- if entry == '$DEBUG_RT':
- self.enforce_debug_rt = True
- continue
-
- if not groups:
- self.options.append(entry)
- else:
- # Substitute special tokens.
- for g in range(0, len(groups)):
- value = groups[g]
-
- # Check for special tokens.
- if entry == ('$CREATE_PATH%d' % g):
- with open(value, 'a'):
- os.utime(value, None)
- continue
-
- if entry == ('$LOAD_PARAMS%d' % g):
- try:
- # The arguments in the params file need to be processed as
- # regular command-line arguments.
- params = [line.rstrip() for line in open(value, 'r')]
- self._ParseArgs(params)
- # Because we have no write permission to orginal params file,
- # create a new params file with addtional suffix
- self.params_file = value + '.msvc'
- except (IOError, e):
- print('Could not open', value, 'for reading:', str(e))
- exit(-1)
- continue
-
- # Regular substitution.
- patterns = {
- '$%d' % g: value,
- '$PATH%d_NO_EXT' % g: self.NormPath(os.path.splitext(value)[0]),
- '$PATH%d' % g: self.NormPath(value),
- }
- pattern = re.compile('(%s)' %
- '|'.join(map(re.escape, patterns.keys())))
- result = pattern.sub(lambda x: patterns[x.group(0)], entry)
- self.options.append(result)
- i += num_matched
- self.leftover = unmatched
-
- # Add in any parsed files
- self.options += files
-
- # Suppress all warning messages if /w is specified
- is_warning_off = '/w' in self.options
- if is_warning_off:
- self.options = [option for option in self.options
- if option not in ['/W2', '/W3', '/W4', '/Wall']]
-
- self.is_cuda_compilation = self.IsCudaCompilation()
- if self.is_cuda_compilation:
- self.GetOptionsForCudaCompilation()
-
- if self.leftover and not is_warning_off:
- print('Warning: Unmatched arguments: ' + ' '.join(self.leftover))
-
- def NormPath(self, path):
- """Uses the current WindowsRunner to normalize the passed path.
-
- Args:
- path: the path to normalize.
-
- Returns:
- A normalized string representing a path suitable for Windows.
- """
- return self.driver.NormPath(path)
-
- def AddOpt(self, option):
- """Adds a single option.
-
- Args:
- option: the option to add.
- """
- self.options.append(option)
-
-
-class WindowsRunner(object):
- """Base class that encapsulates the details of running a binary."""
-
- def NormPath(self, path):
- """Normalizes an input unix style path to a < MAX_PATH char Windows format.
-
- Windows paths cannot be greater than MAX_PATH characters.
-
- Args:
- path: A path in unix format.
-
- Returns:
- An absolute path in Windows format, rooted from some
- directory.
-
- Raises:
- Error: if path is too long
- """
- abspath = os.path.abspath(path)
- # We must allow for the drive letter as well, which is three characters, and
- # the length of any compiler option ahead of the path,
- if len(abspath) >= MAX_PATH_ADJUSTED:
- print(
- 'Warning: path "%s" is >= %d characters (%d); programs may crash '
- 'with long arguments'
- % (str(abspath), MAX_PATH_ADJUSTED, len(abspath)))
- return abspath
-
- def RunBinary(self, binary, args, parser):
- """Runs binary on Windows with the passed args.
-
- Args:
- binary: The binary to run.
- args: The arguments to pass to binary.
- parser: An ArgParser that contains parsed arguments.
-
- Returns:
- The return code from executing binary.
- """
-
- # Run the command.
- if parser.params_file:
- try:
- # Using parameter file as input when linking static libraries.
- params_file = open(parser.params_file, 'w')
- for arg in args:
- params_file.write(('"%s"' % arg) if os.path.isfile(arg) else arg)
- params_file.write('\n')
- params_file.close()
- except (IOError, e):
- print('Could not open', parser.params_file, 'for writing:', str(e))
- exit(-1)
- cmd = [binary] + [('@' + os.path.normpath(parser.params_file))]
- else:
- cmd = [binary] + args
- # Save stderr output to a temporary in case we need it.
- # Unconmment the following line to see what exact command is executed.
- # print("Running: " + " ".join(cmd))
- proc = subprocess.Popen(cmd,
- stdout=sys.stdout,
- stderr=sys.stderr,
- env=os.environ.copy(),
- shell=True)
- proc.wait()
- return proc.returncode