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_USE_CPP_ONLY_TOOLCHAIN", 50 "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", 51 ], 52 implementation = cc_autoconf_toolchains_impl, 53 configure = True, 54) 55 56def cc_autoconf_impl(repository_ctx, overriden_tools = dict()): 57 """Generate BUILD file with 'cc_toolchain' targets for the local host C++ toolchain. 58 59 Args: 60 repository_ctx: repository context 61 overriden_tools: dict of tool paths to use instead of autoconfigured tools 62 """ 63 64 env = repository_ctx.os.environ 65 cpu_value = get_cpu_value(repository_ctx) 66 if "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" in env and env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] == "1": 67 paths = resolve_labels(repository_ctx, [ 68 "@rules_cc//cc/private/toolchain:BUILD.empty", 69 "@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl", 70 ]) 71 repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl") 72 repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:BUILD.empty"], "BUILD") 73 elif cpu_value == "freebsd": 74 paths = resolve_labels(repository_ctx, [ 75 "@rules_cc//cc/private/toolchain:BUILD.static.freebsd", 76 "@rules_cc//cc/private/toolchain:freebsd_cc_toolchain_config.bzl", 77 ]) 78 79 # This is defaulting to a static crosstool, we should eventually 80 # autoconfigure this platform too. Theorically, FreeBSD should be 81 # straightforward to add but we cannot run it in a docker container so 82 # skipping until we have proper tests for FreeBSD. 83 repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:freebsd_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl") 84 repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:BUILD.static.freebsd"], "BUILD") 85 elif cpu_value == "x64_windows": 86 # TODO(ibiryukov): overriden_tools are only supported in configure_unix_toolchain. 87 # We might want to add that to Windows too(at least for msys toolchain). 88 configure_windows_toolchain(repository_ctx) 89 else: 90 configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools) 91 92MSVC_ENVVARS = [ 93 "BAZEL_VC", 94 "BAZEL_VC_FULL_VERSION", 95 "BAZEL_VS", 96 "BAZEL_WINSDK_FULL_VERSION", 97 "VS90COMNTOOLS", 98 "VS100COMNTOOLS", 99 "VS110COMNTOOLS", 100 "VS120COMNTOOLS", 101 "VS140COMNTOOLS", 102 "VS150COMNTOOLS", 103 "VS160COMNTOOLS", 104 "TMP", 105 "TEMP", 106] 107 108cc_autoconf = repository_rule( 109 environ = [ 110 "ABI_LIBC_VERSION", 111 "ABI_VERSION", 112 "BAZEL_COMPILER", 113 "BAZEL_HOST_SYSTEM", 114 "BAZEL_CXXOPTS", 115 "BAZEL_LINKOPTS", 116 "BAZEL_LINKLIBS", 117 "BAZEL_PYTHON", 118 "BAZEL_SH", 119 "BAZEL_TARGET_CPU", 120 "BAZEL_TARGET_LIBC", 121 "BAZEL_TARGET_SYSTEM", 122 "BAZEL_USE_CPP_ONLY_TOOLCHAIN", 123 "BAZEL_USE_XCODE_TOOLCHAIN", 124 "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", 125 "BAZEL_USE_LLVM_NATIVE_COVERAGE", 126 "BAZEL_LLVM", 127 "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS", 128 "USE_CLANG_CL", 129 "CC", 130 "CC_CONFIGURE_DEBUG", 131 "CC_TOOLCHAIN_NAME", 132 "CPLUS_INCLUDE_PATH", 133 "GCOV", 134 "HOMEBREW_RUBY_PATH", 135 "SYSTEMROOT", 136 ] + MSVC_ENVVARS, 137 implementation = cc_autoconf_impl, 138 configure = True, 139) 140 141# buildifier: disable=unnamed-macro 142def cc_configure(): 143 """A C++ configuration rules that generate the crosstool file.""" 144 cc_autoconf_toolchains(name = "local_config_cc_toolchains") 145 cc_autoconf(name = "local_config_cc") 146 native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain") 147 native.register_toolchains( 148 # Use register_toolchain's target pattern expansion to register all toolchains in the package. 149 "@local_config_cc_toolchains//:all", 150 ) 151