1# pylint: disable=g-bad-file-header 2# Copyright 2016 The Bazel Authors. All rights reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16""" 17Helpers for CC Toolchains. 18 19Rules that require a CC toolchain should call `use_cc_toolchain` and `find_cc_toolchain` 20to depend on and find a cc toolchain. 21 22* When https://github.com/bazelbuild/bazel/issues/7260 is **not** flipped, current 23 C++ toolchain is selected using the legacy mechanism (`--crosstool_top`, 24 `--cpu`, `--compiler`). For that to work the rule needs to declare an 25 `_cc_toolchain` attribute, e.g. 26 27 foo = rule( 28 implementation = _foo_impl, 29 attrs = { 30 "_cc_toolchain": attr.label( 31 default = Label( 32 "@rules_cc//cc:current_cc_toolchain", # copybara-use-repo-external-label 33 ), 34 ), 35 }, 36 ) 37 38* When https://github.com/bazelbuild/bazel/issues/7260 **is** flipped, current 39 C++ toolchain is selected using the toolchain resolution mechanism 40 (`--platforms`). For that to work the rule needs to declare a dependency on 41 C++ toolchain type: 42 43 load(":find_cc_toolchain/bzl", "use_cc_toolchain") 44 45 foo = rule( 46 implementation = _foo_impl, 47 toolchains = use_cc_toolchain(), 48 ) 49 50We advise to depend on both `_cc_toolchain` attr and on the toolchain type for 51the duration of the migration. After 52https://github.com/bazelbuild/bazel/issues/7260 is flipped (and support for old 53Bazel version is not needed), it's enough to only keep the toolchain type. 54""" 55 56CC_TOOLCHAIN_TYPE = "@bazel_tools//tools/cpp:toolchain_type" # copybara-use-repo-external-label 57 58def find_cc_toolchain(ctx): 59 """ 60Returns the current `CcToolchainInfo`. 61 62 Args: 63 ctx: The rule context for which to find a toolchain. 64 65 Returns: 66 A CcToolchainInfo. 67 """ 68 69 # Check the incompatible flag for toolchain resolution. 70 if hasattr(cc_common, "is_cc_toolchain_resolution_enabled_do_not_use") and cc_common.is_cc_toolchain_resolution_enabled_do_not_use(ctx = ctx): 71 if not CC_TOOLCHAIN_TYPE in ctx.toolchains: 72 fail("In order to use find_cc_toolchain, your rule has to depend on C++ toolchain. See find_cc_toolchain.bzl docs for details.") 73 toolchain_info = ctx.toolchains[CC_TOOLCHAIN_TYPE] 74 if toolchain_info == None: 75 # No cpp toolchain was found, so report an error. 76 fail("Unable to find a CC toolchain using toolchain resolution. Target: %s, Platform: %s, Exec platform: %s" % 77 (ctx.label, ctx.fragments.platform.platform, ctx.fragments.platform.host_platform)) 78 if hasattr(toolchain_info, "cc_provider_in_toolchain") and hasattr(toolchain_info, "cc"): 79 return toolchain_info.cc 80 return toolchain_info 81 82 # Fall back to the legacy implicit attribute lookup. 83 if hasattr(ctx.attr, "_cc_toolchain"): 84 return ctx.attr._cc_toolchain[cc_common.CcToolchainInfo] 85 86 # We didn't find anything. 87 fail("In order to use find_cc_toolchain, your rule has to depend on C++ toolchain. See find_cc_toolchain.bzl docs for details.") 88 89def find_cpp_toolchain(ctx): 90 """Deprecated, use `find_cc_toolchain` instead. 91 92 Args: 93 ctx: See `find_cc_toolchain`. 94 95 Returns: 96 A CcToolchainInfo. 97 """ 98 return find_cc_toolchain(ctx) 99 100def use_cc_toolchain(mandatory = False): 101 """ 102 Helper to depend on the cc toolchain. 103 104 Usage: 105 ``` 106 my_rule = rule( 107 toolchains = [other toolchain types] + use_cc_toolchain(), 108 ) 109 ``` 110 111 Args: 112 mandatory: Whether or not it should be an error if the toolchain cannot be resolved. 113 114 Returns: 115 A list that can be used as the value for `rule.toolchains`. 116 """ 117 return [config_common.toolchain_type(CC_TOOLCHAIN_TYPE, mandatory = mandatory)] 118