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