• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#    http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Rules for configuring the C++ toolchain (experimental)."""
15
16load(
17    ":lib_cc_configure.bzl",
18    "get_cpu_value",
19    "resolve_labels",
20)
21load(":unix_cc_configure.bzl", "configure_unix_toolchain")
22load(":windows_cc_configure.bzl", "configure_windows_toolchain")
23
24def cc_autoconf_toolchains_impl(repository_ctx):
25    """Generate BUILD file with 'toolchain' targets for the local host C++ toolchain.
26
27    Args:
28      repository_ctx: repository context
29    """
30    env = repository_ctx.os.environ
31
32    # Should we try to find C++ toolchain at all? If not, we don't have to generate toolchains for C++ at all.
33    should_detect_cpp_toolchain = "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" not in env or env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] != "1"
34
35    if should_detect_cpp_toolchain:
36        paths = resolve_labels(repository_ctx, [
37            "@rules_cc//cc/private/toolchain:BUILD.toolchains.tpl",
38        ])
39        repository_ctx.template(
40            "BUILD",
41            paths["@rules_cc//cc/private/toolchain:BUILD.toolchains.tpl"],
42            {"%{name}": get_cpu_value(repository_ctx)},
43        )
44    else:
45        repository_ctx.file("BUILD", "# C++ toolchain autoconfiguration was disabled by BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN env variable.")
46
47cc_autoconf_toolchains = repository_rule(
48    environ = [
49        "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
50    ],
51    implementation = cc_autoconf_toolchains_impl,
52    configure = True,
53)
54
55def cc_autoconf_impl(repository_ctx, overriden_tools = dict()):
56    """Generate BUILD file with 'cc_toolchain' targets for the local host C++ toolchain.
57
58    Args:
59       repository_ctx: repository context
60       overriden_tools: dict of tool paths to use instead of autoconfigured tools
61    """
62
63    env = repository_ctx.os.environ
64    cpu_value = get_cpu_value(repository_ctx)
65    if "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" in env and env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] == "1":
66        paths = resolve_labels(repository_ctx, [
67            "@rules_cc//cc/private/toolchain:BUILD.empty.tpl",
68            "@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl",
69        ])
70        repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl")
71        repository_ctx.template("BUILD", paths["@rules_cc//cc/private/toolchain:BUILD.empty.tpl"], {
72            "%{cpu}": get_cpu_value(repository_ctx),
73        })
74    elif cpu_value == "freebsd" or cpu_value == "openbsd":
75        paths = resolve_labels(repository_ctx, [
76            "@rules_cc//cc/private/toolchain:BUILD.static.bsd",
77            "@rules_cc//cc/private/toolchain:bsd_cc_toolchain_config.bzl",
78        ])
79
80        # This is defaulting to a static crosstool. We should eventually
81        # autoconfigure this platform too. Theoretically, FreeBSD and OpenBSD
82        # should be straightforward to add but we cannot run them in a Docker
83        # container so skipping until we have proper tests for these platforms.
84        repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:bsd_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl")
85        repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:BUILD.static.bsd"], "BUILD")
86    elif cpu_value in ["x64_windows", "arm64_windows"]:
87        # TODO(ibiryukov): overriden_tools are only supported in configure_unix_toolchain.
88        # We might want to add that to Windows too(at least for msys toolchain).
89        configure_windows_toolchain(repository_ctx)
90    else:
91        configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools)
92
93MSVC_ENVVARS = [
94    "BAZEL_VC",
95    "BAZEL_VC_FULL_VERSION",
96    "BAZEL_VS",
97    "BAZEL_WINSDK_FULL_VERSION",
98    "VS90COMNTOOLS",
99    "VS100COMNTOOLS",
100    "VS110COMNTOOLS",
101    "VS120COMNTOOLS",
102    "VS140COMNTOOLS",
103    "VS150COMNTOOLS",
104    "VS160COMNTOOLS",
105    "TMP",
106    "TEMP",
107]
108
109cc_autoconf = repository_rule(
110    environ = [
111        "ABI_LIBC_VERSION",
112        "ABI_VERSION",
113        "BAZEL_COMPILER",
114        "BAZEL_HOST_SYSTEM",
115        "BAZEL_CONLYOPTS",
116        "BAZEL_CXXOPTS",
117        "BAZEL_LINKOPTS",
118        "BAZEL_LINKLIBS",
119        "BAZEL_LLVM_COV",
120        "BAZEL_LLVM_PROFDATA",
121        "BAZEL_PYTHON",
122        "BAZEL_SH",
123        "BAZEL_TARGET_CPU",
124        "BAZEL_TARGET_LIBC",
125        "BAZEL_TARGET_SYSTEM",
126        "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
127        "BAZEL_USE_LLVM_NATIVE_COVERAGE",
128        "BAZEL_LLVM",
129        "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS",
130        "USE_CLANG_CL",
131        "CC",
132        "CC_CONFIGURE_DEBUG",
133        "CC_TOOLCHAIN_NAME",
134        "CPLUS_INCLUDE_PATH",
135        "DEVELOPER_DIR",
136        "GCOV",
137        "LIBTOOL",
138        "HOMEBREW_RUBY_PATH",
139        "SYSTEMROOT",
140        "USER",
141    ] + MSVC_ENVVARS,
142    implementation = cc_autoconf_impl,
143    configure = True,
144)
145
146# buildifier: disable=unnamed-macro
147def cc_configure():
148    """A C++ configuration rules that generate the crosstool file."""
149    cc_autoconf_toolchains(name = "local_config_cc_toolchains")
150    cc_autoconf(name = "local_config_cc")
151    native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain")
152    native.register_toolchains(
153        # Use register_toolchain's target pattern expansion to register all toolchains in the package.
154        "@local_config_cc_toolchains//:all",
155    )
156