# 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. """Rules for configuring the C++ toolchain (experimental).""" load( ":lib_cc_configure.bzl", "get_cpu_value", "resolve_labels", ) load(":unix_cc_configure.bzl", "configure_unix_toolchain") load(":windows_cc_configure.bzl", "configure_windows_toolchain") def cc_autoconf_toolchains_impl(repository_ctx): """Generate BUILD file with 'toolchain' targets for the local host C++ toolchain. Args: repository_ctx: repository context """ env = repository_ctx.os.environ # Should we try to find C++ toolchain at all? If not, we don't have to generate toolchains for C++ at all. should_detect_cpp_toolchain = "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" not in env or env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] != "1" if should_detect_cpp_toolchain: paths = resolve_labels(repository_ctx, [ "@rules_cc//cc/private/toolchain:BUILD.toolchains.tpl", ]) repository_ctx.template( "BUILD", paths["@rules_cc//cc/private/toolchain:BUILD.toolchains.tpl"], {"%{name}": get_cpu_value(repository_ctx)}, ) else: repository_ctx.file("BUILD", "# C++ toolchain autoconfiguration was disabled by BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN env variable.") cc_autoconf_toolchains = repository_rule( environ = [ "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", ], implementation = cc_autoconf_toolchains_impl, configure = True, ) def cc_autoconf_impl(repository_ctx, overriden_tools = dict()): """Generate BUILD file with 'cc_toolchain' targets for the local host C++ toolchain. Args: repository_ctx: repository context overriden_tools: dict of tool paths to use instead of autoconfigured tools """ env = repository_ctx.os.environ cpu_value = get_cpu_value(repository_ctx) if "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" in env and env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] == "1": paths = resolve_labels(repository_ctx, [ "@rules_cc//cc/private/toolchain:BUILD.empty.tpl", "@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl", ]) repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl") repository_ctx.template("BUILD", paths["@rules_cc//cc/private/toolchain:BUILD.empty.tpl"], { "%{cpu}": get_cpu_value(repository_ctx), }) elif cpu_value == "freebsd" or cpu_value == "openbsd": paths = resolve_labels(repository_ctx, [ "@rules_cc//cc/private/toolchain:BUILD.static.bsd", "@rules_cc//cc/private/toolchain:bsd_cc_toolchain_config.bzl", ]) # This is defaulting to a static crosstool. We should eventually # autoconfigure this platform too. Theoretically, FreeBSD and OpenBSD # should be straightforward to add but we cannot run them in a Docker # container so skipping until we have proper tests for these platforms. repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:bsd_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl") repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:BUILD.static.bsd"], "BUILD") elif cpu_value in ["x64_windows", "arm64_windows"]: # TODO(ibiryukov): overriden_tools are only supported in configure_unix_toolchain. # We might want to add that to Windows too(at least for msys toolchain). configure_windows_toolchain(repository_ctx) else: configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools) MSVC_ENVVARS = [ "BAZEL_VC", "BAZEL_VC_FULL_VERSION", "BAZEL_VS", "BAZEL_WINSDK_FULL_VERSION", "VS90COMNTOOLS", "VS100COMNTOOLS", "VS110COMNTOOLS", "VS120COMNTOOLS", "VS140COMNTOOLS", "VS150COMNTOOLS", "VS160COMNTOOLS", "TMP", "TEMP", ] cc_autoconf = repository_rule( environ = [ "ABI_LIBC_VERSION", "ABI_VERSION", "BAZEL_COMPILER", "BAZEL_HOST_SYSTEM", "BAZEL_CONLYOPTS", "BAZEL_CXXOPTS", "BAZEL_LINKOPTS", "BAZEL_LINKLIBS", "BAZEL_LLVM_COV", "BAZEL_LLVM_PROFDATA", "BAZEL_PYTHON", "BAZEL_SH", "BAZEL_TARGET_CPU", "BAZEL_TARGET_LIBC", "BAZEL_TARGET_SYSTEM", "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", "BAZEL_USE_LLVM_NATIVE_COVERAGE", "BAZEL_LLVM", "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS", "USE_CLANG_CL", "CC", "CC_CONFIGURE_DEBUG", "CC_TOOLCHAIN_NAME", "CPLUS_INCLUDE_PATH", "DEVELOPER_DIR", "GCOV", "LIBTOOL", "HOMEBREW_RUBY_PATH", "SYSTEMROOT", "USER", ] + MSVC_ENVVARS, implementation = cc_autoconf_impl, configure = True, ) # buildifier: disable=unnamed-macro def cc_configure(): """A C++ configuration rules that generate the crosstool file.""" cc_autoconf_toolchains(name = "local_config_cc_toolchains") cc_autoconf(name = "local_config_cc") native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain") native.register_toolchains( # Use register_toolchain's target pattern expansion to register all toolchains in the package. "@local_config_cc_toolchains//:all", )