1*9bb1b549SSpandan Das# Copyright 2020 The Bazel Authors. All rights reserved. 2*9bb1b549SSpandan Das# 3*9bb1b549SSpandan Das# Licensed under the Apache License, Version 2.0 (the "License"); 4*9bb1b549SSpandan Das# you may not use this file except in compliance with the License. 5*9bb1b549SSpandan Das# You may obtain a copy of the License at 6*9bb1b549SSpandan Das# 7*9bb1b549SSpandan Das# http://www.apache.org/licenses/LICENSE-2.0 8*9bb1b549SSpandan Das# 9*9bb1b549SSpandan Das# Unless required by applicable law or agreed to in writing, software 10*9bb1b549SSpandan Das# distributed under the License is distributed on an "AS IS" BASIS, 11*9bb1b549SSpandan Das# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9bb1b549SSpandan Das# See the License for the specific language governing permissions and 13*9bb1b549SSpandan Das# limitations under the License. 14*9bb1b549SSpandan Das 15*9bb1b549SSpandan Dasload( 16*9bb1b549SSpandan Das "@bazel_skylib//lib:paths.bzl", 17*9bb1b549SSpandan Das "paths", 18*9bb1b549SSpandan Das) 19*9bb1b549SSpandan Dasload( 20*9bb1b549SSpandan Das "//go/private:mode.bzl", 21*9bb1b549SSpandan Das "LINKMODES", 22*9bb1b549SSpandan Das "LINKMODE_NORMAL", 23*9bb1b549SSpandan Das) 24*9bb1b549SSpandan Dasload( 25*9bb1b549SSpandan Das "//go/private:platforms.bzl", 26*9bb1b549SSpandan Das "CGO_GOOS_GOARCH", 27*9bb1b549SSpandan Das "GOOS_GOARCH", 28*9bb1b549SSpandan Das) 29*9bb1b549SSpandan Dasload( 30*9bb1b549SSpandan Das "//go/private:providers.bzl", 31*9bb1b549SSpandan Das "GoArchive", 32*9bb1b549SSpandan Das "GoLibrary", 33*9bb1b549SSpandan Das "GoSource", 34*9bb1b549SSpandan Das) 35*9bb1b549SSpandan Das 36*9bb1b549SSpandan Das# A list of rules_go settings that are possibly set by go_transition. 37*9bb1b549SSpandan Das# Keep their package name in sync with the implementation of 38*9bb1b549SSpandan Das# _original_setting_key. 39*9bb1b549SSpandan DasTRANSITIONED_GO_SETTING_KEYS = [ 40*9bb1b549SSpandan Das "//go/config:static", 41*9bb1b549SSpandan Das "//go/config:msan", 42*9bb1b549SSpandan Das "//go/config:race", 43*9bb1b549SSpandan Das "//go/config:pure", 44*9bb1b549SSpandan Das "//go/config:linkmode", 45*9bb1b549SSpandan Das "//go/config:tags", 46*9bb1b549SSpandan Das] 47*9bb1b549SSpandan Das 48*9bb1b549SSpandan Dasdef _deduped_and_sorted(strs): 49*9bb1b549SSpandan Das return sorted({s: None for s in strs}.keys()) 50*9bb1b549SSpandan Das 51*9bb1b549SSpandan Dasdef _original_setting_key(key): 52*9bb1b549SSpandan Das if not "//go/config:" in key: 53*9bb1b549SSpandan Das fail("_original_setting_key currently assumes that all Go settings live under //go/config, got: " + key) 54*9bb1b549SSpandan Das name = key.split(":")[1] 55*9bb1b549SSpandan Das return "//go/private/rules:original_" + name 56*9bb1b549SSpandan Das 57*9bb1b549SSpandan Das_SETTING_KEY_TO_ORIGINAL_SETTING_KEY = { 58*9bb1b549SSpandan Das setting: _original_setting_key(setting) 59*9bb1b549SSpandan Das for setting in TRANSITIONED_GO_SETTING_KEYS 60*9bb1b549SSpandan Das} 61*9bb1b549SSpandan Das 62*9bb1b549SSpandan Dasdef _go_transition_impl(settings, attr): 63*9bb1b549SSpandan Das # NOTE: Keep the list of rules_go settings set by this transition in sync 64*9bb1b549SSpandan Das # with POTENTIALLY_TRANSITIONED_SETTINGS. 65*9bb1b549SSpandan Das # 66*9bb1b549SSpandan Das # NOTE(bazelbuild/bazel#11409): Calling fail here for invalid combinations 67*9bb1b549SSpandan Das # of flags reports an error but does not stop the build. 68*9bb1b549SSpandan Das # In any case, get_mode should mainly be responsible for reporting 69*9bb1b549SSpandan Das # invalid modes, since it also takes --features flags into account. 70*9bb1b549SSpandan Das 71*9bb1b549SSpandan Das original_settings = settings 72*9bb1b549SSpandan Das settings = dict(settings) 73*9bb1b549SSpandan Das 74*9bb1b549SSpandan Das _set_ternary(settings, attr, "static") 75*9bb1b549SSpandan Das race = _set_ternary(settings, attr, "race") 76*9bb1b549SSpandan Das msan = _set_ternary(settings, attr, "msan") 77*9bb1b549SSpandan Das pure = _set_ternary(settings, attr, "pure") 78*9bb1b549SSpandan Das if race == "on": 79*9bb1b549SSpandan Das if pure == "on": 80*9bb1b549SSpandan Das fail('race = "on" cannot be set when pure = "on" is set. race requires cgo.') 81*9bb1b549SSpandan Das pure = "off" 82*9bb1b549SSpandan Das settings["//go/config:pure"] = False 83*9bb1b549SSpandan Das if msan == "on": 84*9bb1b549SSpandan Das if pure == "on": 85*9bb1b549SSpandan Das fail('msan = "on" cannot be set when msan = "on" is set. msan requires cgo.') 86*9bb1b549SSpandan Das pure = "off" 87*9bb1b549SSpandan Das settings["//go/config:pure"] = False 88*9bb1b549SSpandan Das if pure == "on": 89*9bb1b549SSpandan Das race = "off" 90*9bb1b549SSpandan Das settings["//go/config:race"] = False 91*9bb1b549SSpandan Das msan = "off" 92*9bb1b549SSpandan Das settings["//go/config:msan"] = False 93*9bb1b549SSpandan Das cgo = pure == "off" 94*9bb1b549SSpandan Das 95*9bb1b549SSpandan Das goos = getattr(attr, "goos", "auto") 96*9bb1b549SSpandan Das goarch = getattr(attr, "goarch", "auto") 97*9bb1b549SSpandan Das _check_ternary("pure", pure) 98*9bb1b549SSpandan Das if goos != "auto" or goarch != "auto": 99*9bb1b549SSpandan Das if goos == "auto": 100*9bb1b549SSpandan Das fail("goos must be set if goarch is set") 101*9bb1b549SSpandan Das if goarch == "auto": 102*9bb1b549SSpandan Das fail("goarch must be set if goos is set") 103*9bb1b549SSpandan Das if (goos, goarch) not in GOOS_GOARCH: 104*9bb1b549SSpandan Das fail("invalid goos, goarch pair: {}, {}".format(goos, goarch)) 105*9bb1b549SSpandan Das if cgo and (goos, goarch) not in CGO_GOOS_GOARCH: 106*9bb1b549SSpandan Das fail('pure is "off" but cgo is not supported on {} {}'.format(goos, goarch)) 107*9bb1b549SSpandan Das platform = "@io_bazel_rules_go//go/toolchain:{}_{}{}".format(goos, goarch, "_cgo" if cgo else "") 108*9bb1b549SSpandan Das settings["//command_line_option:platforms"] = platform 109*9bb1b549SSpandan Das 110*9bb1b549SSpandan Das tags = getattr(attr, "gotags", []) 111*9bb1b549SSpandan Das if tags: 112*9bb1b549SSpandan Das settings["//go/config:tags"] = _deduped_and_sorted(tags) 113*9bb1b549SSpandan Das 114*9bb1b549SSpandan Das linkmode = getattr(attr, "linkmode", "auto") 115*9bb1b549SSpandan Das if linkmode != "auto": 116*9bb1b549SSpandan Das if linkmode not in LINKMODES: 117*9bb1b549SSpandan Das fail("linkmode: invalid mode {}; want one of {}".format(linkmode, ", ".join(LINKMODES))) 118*9bb1b549SSpandan Das settings["//go/config:linkmode"] = linkmode 119*9bb1b549SSpandan Das 120*9bb1b549SSpandan Das for key, original_key in _SETTING_KEY_TO_ORIGINAL_SETTING_KEY.items(): 121*9bb1b549SSpandan Das old_value = original_settings[key] 122*9bb1b549SSpandan Das value = settings[key] 123*9bb1b549SSpandan Das 124*9bb1b549SSpandan Das # If the outgoing configuration would differ from the incoming one in a 125*9bb1b549SSpandan Das # value, record the old value in the special original_* key so that the 126*9bb1b549SSpandan Das # real setting can be reset to this value before the new configuration 127*9bb1b549SSpandan Das # would cross a non-deps dependency edge. 128*9bb1b549SSpandan Das if value != old_value: 129*9bb1b549SSpandan Das # Encoding as JSON makes it possible to embed settings of arbitrary 130*9bb1b549SSpandan Das # types (currently bool, string and string_list) into a single type 131*9bb1b549SSpandan Das # of setting (string) with the information preserved whether the 132*9bb1b549SSpandan Das # original setting wasn't set explicitly (empty string) or was set 133*9bb1b549SSpandan Das # explicitly to its default (always a non-empty string with JSON 134*9bb1b549SSpandan Das # encoding, e.g. "\"\"" or "[]"). 135*9bb1b549SSpandan Das settings[original_key] = json.encode(old_value) 136*9bb1b549SSpandan Das else: 137*9bb1b549SSpandan Das settings[original_key] = "" 138*9bb1b549SSpandan Das 139*9bb1b549SSpandan Das return settings 140*9bb1b549SSpandan Das 141*9bb1b549SSpandan Dasdef _request_nogo_transition(settings, _attr): 142*9bb1b549SSpandan Das """Indicates that we want the project configured nogo instead of a noop. 143*9bb1b549SSpandan Das 144*9bb1b549SSpandan Das This does not guarantee that the project configured nogo will be used (if 145*9bb1b549SSpandan Das bootstrap is true we are currently building nogo so that is a cyclic 146*9bb1b549SSpandan Das dependency). 147*9bb1b549SSpandan Das 148*9bb1b549SSpandan Das The config setting nogo_active requires bootstrap to be false and 149*9bb1b549SSpandan Das request_nogo to be true to provide the project configured nogo. 150*9bb1b549SSpandan Das """ 151*9bb1b549SSpandan Das settings = dict(settings) 152*9bb1b549SSpandan Das settings["//go/private:request_nogo"] = True 153*9bb1b549SSpandan Das return settings 154*9bb1b549SSpandan Das 155*9bb1b549SSpandan Dasrequest_nogo_transition = transition( 156*9bb1b549SSpandan Das implementation = _request_nogo_transition, 157*9bb1b549SSpandan Das inputs = [], 158*9bb1b549SSpandan Das outputs = ["//go/private:request_nogo"], 159*9bb1b549SSpandan Das) 160*9bb1b549SSpandan Das 161*9bb1b549SSpandan Dasgo_transition = transition( 162*9bb1b549SSpandan Das implementation = _go_transition_impl, 163*9bb1b549SSpandan Das inputs = [ 164*9bb1b549SSpandan Das "//command_line_option:platforms", 165*9bb1b549SSpandan Das ] + TRANSITIONED_GO_SETTING_KEYS, 166*9bb1b549SSpandan Das outputs = [ 167*9bb1b549SSpandan Das "//command_line_option:platforms", 168*9bb1b549SSpandan Das ] + TRANSITIONED_GO_SETTING_KEYS + _SETTING_KEY_TO_ORIGINAL_SETTING_KEY.values(), 169*9bb1b549SSpandan Das) 170*9bb1b549SSpandan Das 171*9bb1b549SSpandan Das_common_reset_transition_dict = dict({ 172*9bb1b549SSpandan Das "//go/private:request_nogo": False, 173*9bb1b549SSpandan Das "//go/config:static": False, 174*9bb1b549SSpandan Das "//go/config:msan": False, 175*9bb1b549SSpandan Das "//go/config:race": False, 176*9bb1b549SSpandan Das "//go/config:pure": False, 177*9bb1b549SSpandan Das "//go/config:debug": False, 178*9bb1b549SSpandan Das "//go/config:linkmode": LINKMODE_NORMAL, 179*9bb1b549SSpandan Das "//go/config:tags": [], 180*9bb1b549SSpandan Das}, **{setting: "" for setting in _SETTING_KEY_TO_ORIGINAL_SETTING_KEY.values()}) 181*9bb1b549SSpandan Das 182*9bb1b549SSpandan Das_reset_transition_dict = dict(_common_reset_transition_dict, **{ 183*9bb1b549SSpandan Das "//go/private:bootstrap_nogo": True, 184*9bb1b549SSpandan Das}) 185*9bb1b549SSpandan Das 186*9bb1b549SSpandan Das_reset_transition_keys = sorted(_reset_transition_dict.keys()) 187*9bb1b549SSpandan Das 188*9bb1b549SSpandan Das_stdlib_keep_keys = sorted([ 189*9bb1b549SSpandan Das "//go/config:msan", 190*9bb1b549SSpandan Das "//go/config:race", 191*9bb1b549SSpandan Das "//go/config:pure", 192*9bb1b549SSpandan Das "//go/config:linkmode", 193*9bb1b549SSpandan Das "//go/config:tags", 194*9bb1b549SSpandan Das]) 195*9bb1b549SSpandan Das 196*9bb1b549SSpandan Dasdef _go_tool_transition_impl(settings, _attr): 197*9bb1b549SSpandan Das """Sets most Go settings to default values (use for external Go tools). 198*9bb1b549SSpandan Das 199*9bb1b549SSpandan Das go_tool_transition sets all of the //go/config settings to their default 200*9bb1b549SSpandan Das values and disables nogo. This is used for Go tool binaries like nogo 201*9bb1b549SSpandan Das itself. Tool binaries shouldn't depend on the link mode or tags of the 202*9bb1b549SSpandan Das target configuration and neither the tools nor the code they potentially 203*9bb1b549SSpandan Das generate should be subject to nogo's static analysis. This transition 204*9bb1b549SSpandan Das doesn't change the platform (goos, goarch), but tool binaries should also 205*9bb1b549SSpandan Das have `cfg = "exec"` so tool binaries should be built for the execution 206*9bb1b549SSpandan Das platform. 207*9bb1b549SSpandan Das """ 208*9bb1b549SSpandan Das return dict(settings, **_reset_transition_dict) 209*9bb1b549SSpandan Das 210*9bb1b549SSpandan Dasgo_tool_transition = transition( 211*9bb1b549SSpandan Das implementation = _go_tool_transition_impl, 212*9bb1b549SSpandan Das inputs = _reset_transition_keys, 213*9bb1b549SSpandan Das outputs = _reset_transition_keys, 214*9bb1b549SSpandan Das) 215*9bb1b549SSpandan Das 216*9bb1b549SSpandan Dasdef _non_go_tool_transition_impl(settings, _attr): 217*9bb1b549SSpandan Das """Sets all Go settings to default values (use for external non-Go tools). 218*9bb1b549SSpandan Das 219*9bb1b549SSpandan Das non_go_tool_transition sets all of the //go/config settings as well as the 220*9bb1b549SSpandan Das nogo settings to their default values. This is used for all tools that are 221*9bb1b549SSpandan Das not themselves targets created from rules_go rules and thus do not read 222*9bb1b549SSpandan Das these settings. Resetting all of them to defaults prevents unnecessary 223*9bb1b549SSpandan Das configuration changes for these targets that could cause rebuilds. 224*9bb1b549SSpandan Das 225*9bb1b549SSpandan Das Examples: This transition is applied to attributes referencing proto_library 226*9bb1b549SSpandan Das targets or protoc directly. 227*9bb1b549SSpandan Das """ 228*9bb1b549SSpandan Das settings = dict(settings, **_reset_transition_dict) 229*9bb1b549SSpandan Das settings["//go/private:bootstrap_nogo"] = False 230*9bb1b549SSpandan Das return settings 231*9bb1b549SSpandan Das 232*9bb1b549SSpandan Dasnon_go_tool_transition = transition( 233*9bb1b549SSpandan Das implementation = _non_go_tool_transition_impl, 234*9bb1b549SSpandan Das inputs = _reset_transition_keys, 235*9bb1b549SSpandan Das outputs = _reset_transition_keys, 236*9bb1b549SSpandan Das) 237*9bb1b549SSpandan Das 238*9bb1b549SSpandan Dasdef _go_stdlib_transition_impl(settings, _attr): 239*9bb1b549SSpandan Das """Sets all Go settings to their default values, except for those affecting the Go SDK. 240*9bb1b549SSpandan Das 241*9bb1b549SSpandan Das This transition is similar to _non_go_tool_transition except that it keeps the 242*9bb1b549SSpandan Das parts of the configuration that determine how to build the standard library. 243*9bb1b549SSpandan Das It's used to consolidate the configurations used to build the standard library to limit 244*9bb1b549SSpandan Das the number built. 245*9bb1b549SSpandan Das """ 246*9bb1b549SSpandan Das settings = dict(settings) 247*9bb1b549SSpandan Das for label, value in _reset_transition_dict.items(): 248*9bb1b549SSpandan Das if label not in _stdlib_keep_keys: 249*9bb1b549SSpandan Das settings[label] = value 250*9bb1b549SSpandan Das settings["//go/config:tags"] = [t for t in settings["//go/config:tags"] if t in _TAG_AFFECTS_STDLIB] 251*9bb1b549SSpandan Das settings["//go/private:bootstrap_nogo"] = False 252*9bb1b549SSpandan Das return settings 253*9bb1b549SSpandan Das 254*9bb1b549SSpandan Dasgo_stdlib_transition = transition( 255*9bb1b549SSpandan Das implementation = _go_stdlib_transition_impl, 256*9bb1b549SSpandan Das inputs = _reset_transition_keys, 257*9bb1b549SSpandan Das outputs = _reset_transition_keys, 258*9bb1b549SSpandan Das) 259*9bb1b549SSpandan Das 260*9bb1b549SSpandan Dasdef _go_reset_target_impl(ctx): 261*9bb1b549SSpandan Das t = ctx.attr.dep[0] # [0] seems to be necessary with the transition 262*9bb1b549SSpandan Das providers = [t[p] for p in [GoLibrary, GoSource, GoArchive] if p in t] 263*9bb1b549SSpandan Das 264*9bb1b549SSpandan Das # We can't pass DefaultInfo through as-is, since Bazel forbids executable 265*9bb1b549SSpandan Das # if it's a file declared in a different target. To emulate that, symlink 266*9bb1b549SSpandan Das # to the original executable, if there is one. 267*9bb1b549SSpandan Das default_info = t[DefaultInfo] 268*9bb1b549SSpandan Das 269*9bb1b549SSpandan Das new_executable = None 270*9bb1b549SSpandan Das original_executable = default_info.files_to_run.executable 271*9bb1b549SSpandan Das default_runfiles = default_info.default_runfiles 272*9bb1b549SSpandan Das if original_executable: 273*9bb1b549SSpandan Das # In order for the symlink to have the same basename as the original 274*9bb1b549SSpandan Das # executable (important in the case of proto plugins), put it in a 275*9bb1b549SSpandan Das # subdirectory named after the label to prevent collisions. 276*9bb1b549SSpandan Das new_executable = ctx.actions.declare_file(paths.join(ctx.label.name, original_executable.basename)) 277*9bb1b549SSpandan Das ctx.actions.symlink( 278*9bb1b549SSpandan Das output = new_executable, 279*9bb1b549SSpandan Das target_file = original_executable, 280*9bb1b549SSpandan Das is_executable = True, 281*9bb1b549SSpandan Das ) 282*9bb1b549SSpandan Das default_runfiles = default_runfiles.merge(ctx.runfiles([new_executable])) 283*9bb1b549SSpandan Das 284*9bb1b549SSpandan Das providers.append( 285*9bb1b549SSpandan Das DefaultInfo( 286*9bb1b549SSpandan Das files = default_info.files, 287*9bb1b549SSpandan Das data_runfiles = default_info.data_runfiles, 288*9bb1b549SSpandan Das default_runfiles = default_runfiles, 289*9bb1b549SSpandan Das executable = new_executable, 290*9bb1b549SSpandan Das ), 291*9bb1b549SSpandan Das ) 292*9bb1b549SSpandan Das return providers 293*9bb1b549SSpandan Das 294*9bb1b549SSpandan Dasgo_reset_target = rule( 295*9bb1b549SSpandan Das implementation = _go_reset_target_impl, 296*9bb1b549SSpandan Das attrs = { 297*9bb1b549SSpandan Das "dep": attr.label( 298*9bb1b549SSpandan Das mandatory = True, 299*9bb1b549SSpandan Das cfg = go_tool_transition, 300*9bb1b549SSpandan Das ), 301*9bb1b549SSpandan Das "_allowlist_function_transition": attr.label( 302*9bb1b549SSpandan Das default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 303*9bb1b549SSpandan Das ), 304*9bb1b549SSpandan Das }, 305*9bb1b549SSpandan Das doc = """Forwards providers from a target and applies go_tool_transition. 306*9bb1b549SSpandan Das 307*9bb1b549SSpandan Dasgo_reset_target depends on a single target, built using go_tool_transition. It 308*9bb1b549SSpandan Dasforwards Go providers and DefaultInfo. 309*9bb1b549SSpandan Das 310*9bb1b549SSpandan DasThis is used to work around a problem with building tools: Go tools should be 311*9bb1b549SSpandan Dasbuilt with 'cfg = "exec"' so they work on the execution platform, but we also 312*9bb1b549SSpandan Dasneed to apply go_tool_transition so that e.g. a tool isn't built as a shared 313*9bb1b549SSpandan Daslibrary with race instrumentation. This acts as an intermediate rule that allows 314*9bb1b549SSpandan Dasto apply both both transitions. 315*9bb1b549SSpandan Das""", 316*9bb1b549SSpandan Das) 317*9bb1b549SSpandan Das 318*9bb1b549SSpandan Dasnon_go_reset_target = rule( 319*9bb1b549SSpandan Das implementation = _go_reset_target_impl, 320*9bb1b549SSpandan Das attrs = { 321*9bb1b549SSpandan Das "dep": attr.label( 322*9bb1b549SSpandan Das mandatory = True, 323*9bb1b549SSpandan Das cfg = non_go_tool_transition, 324*9bb1b549SSpandan Das ), 325*9bb1b549SSpandan Das "_allowlist_function_transition": attr.label( 326*9bb1b549SSpandan Das default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 327*9bb1b549SSpandan Das ), 328*9bb1b549SSpandan Das }, 329*9bb1b549SSpandan Das doc = """Forwards providers from a target and applies non_go_tool_transition. 330*9bb1b549SSpandan Das 331*9bb1b549SSpandan Dasnon_go_reset_target depends on a single target, built using 332*9bb1b549SSpandan Dasnon_go_tool_transition. It forwards Go providers and DefaultInfo. 333*9bb1b549SSpandan Das 334*9bb1b549SSpandan DasThis is used to work around a problem with building tools: Non-Go tools should 335*9bb1b549SSpandan Dasbe built with 'cfg = "exec"' so they work on the execution platform, but they 336*9bb1b549SSpandan Dasalso shouldn't be affected by Go-specific config changes applied by 337*9bb1b549SSpandan Dasgo_transition. 338*9bb1b549SSpandan Das""", 339*9bb1b549SSpandan Das) 340*9bb1b549SSpandan Das 341*9bb1b549SSpandan Dasdef _non_go_transition_impl(settings, _attr): 342*9bb1b549SSpandan Das """Sets all Go settings to the values they had before the last go_transition. 343*9bb1b549SSpandan Das 344*9bb1b549SSpandan Das non_go_transition sets all of the //go/config settings to the value they had 345*9bb1b549SSpandan Das before the last go_transition. This should be used on all attributes of 346*9bb1b549SSpandan Das go_library/go_binary/go_test that are built in the target configuration and 347*9bb1b549SSpandan Das do not constitute advertise any Go providers. 348*9bb1b549SSpandan Das 349*9bb1b549SSpandan Das Examples: This transition is applied to the 'data' attribute of go_binary so 350*9bb1b549SSpandan Das that other Go binaries used at runtime aren't affected by a non-standard 351*9bb1b549SSpandan Das link mode set on the go_binary target, but still use the same top-level 352*9bb1b549SSpandan Das settings such as e.g. race instrumentation. 353*9bb1b549SSpandan Das """ 354*9bb1b549SSpandan Das new_settings = {} 355*9bb1b549SSpandan Das for key, original_key in _SETTING_KEY_TO_ORIGINAL_SETTING_KEY.items(): 356*9bb1b549SSpandan Das original_value = settings[original_key] 357*9bb1b549SSpandan Das if original_value: 358*9bb1b549SSpandan Das # Reset to the original value of the setting before go_transition. 359*9bb1b549SSpandan Das new_settings[key] = json.decode(original_value) 360*9bb1b549SSpandan Das else: 361*9bb1b549SSpandan Das new_settings[key] = settings[key] 362*9bb1b549SSpandan Das 363*9bb1b549SSpandan Das # Reset the value of the helper setting to its default for two reasons: 364*9bb1b549SSpandan Das # 1. Performance: This ensures that the Go settings of non-Go 365*9bb1b549SSpandan Das # dependencies have the same values as before the go_transition, 366*9bb1b549SSpandan Das # which can prevent unnecessary rebuilds caused by configuration 367*9bb1b549SSpandan Das # changes. 368*9bb1b549SSpandan Das # 2. Correctness in edge cases: If there is a path in the build graph 369*9bb1b549SSpandan Das # from a go_binary's non-Go dependency to a go_library that does not 370*9bb1b549SSpandan Das # pass through another go_binary (e.g., through a custom rule 371*9bb1b549SSpandan Das # replacement for go_binary), this transition could be applied again 372*9bb1b549SSpandan Das # and cause incorrect Go setting values. 373*9bb1b549SSpandan Das new_settings[original_key] = "" 374*9bb1b549SSpandan Das 375*9bb1b549SSpandan Das return new_settings 376*9bb1b549SSpandan Das 377*9bb1b549SSpandan Dasnon_go_transition = transition( 378*9bb1b549SSpandan Das implementation = _non_go_transition_impl, 379*9bb1b549SSpandan Das inputs = TRANSITIONED_GO_SETTING_KEYS + _SETTING_KEY_TO_ORIGINAL_SETTING_KEY.values(), 380*9bb1b549SSpandan Das outputs = TRANSITIONED_GO_SETTING_KEYS + _SETTING_KEY_TO_ORIGINAL_SETTING_KEY.values(), 381*9bb1b549SSpandan Das) 382*9bb1b549SSpandan Das 383*9bb1b549SSpandan Dasdef _check_ternary(name, value): 384*9bb1b549SSpandan Das if value not in ("on", "off", "auto"): 385*9bb1b549SSpandan Das fail('{}: must be "on", "off", or "auto"'.format(name)) 386*9bb1b549SSpandan Das 387*9bb1b549SSpandan Dasdef _set_ternary(settings, attr, name): 388*9bb1b549SSpandan Das value = getattr(attr, name, "auto") 389*9bb1b549SSpandan Das _check_ternary(name, value) 390*9bb1b549SSpandan Das if value != "auto": 391*9bb1b549SSpandan Das label = "//go/config:{}".format(name) 392*9bb1b549SSpandan Das settings[label] = value == "on" 393*9bb1b549SSpandan Das return value 394*9bb1b549SSpandan Das 395*9bb1b549SSpandan Das_SDK_VERSION_BUILD_SETTING = "//go/toolchain:sdk_version" 396*9bb1b549SSpandan DasTRANSITIONED_GO_CROSS_SETTING_KEYS = [ 397*9bb1b549SSpandan Das _SDK_VERSION_BUILD_SETTING, 398*9bb1b549SSpandan Das "//command_line_option:platforms", 399*9bb1b549SSpandan Das] 400*9bb1b549SSpandan Das 401*9bb1b549SSpandan Dasdef _go_cross_transition_impl(settings, attr): 402*9bb1b549SSpandan Das settings = dict(settings) 403*9bb1b549SSpandan Das if attr.sdk_version != None: 404*9bb1b549SSpandan Das settings[_SDK_VERSION_BUILD_SETTING] = attr.sdk_version 405*9bb1b549SSpandan Das 406*9bb1b549SSpandan Das if attr.platform != None: 407*9bb1b549SSpandan Das settings["//command_line_option:platforms"] = str(attr.platform) 408*9bb1b549SSpandan Das 409*9bb1b549SSpandan Das return settings 410*9bb1b549SSpandan Das 411*9bb1b549SSpandan Dasgo_cross_transition = transition( 412*9bb1b549SSpandan Das implementation = _go_cross_transition_impl, 413*9bb1b549SSpandan Das inputs = TRANSITIONED_GO_CROSS_SETTING_KEYS, 414*9bb1b549SSpandan Das outputs = TRANSITIONED_GO_CROSS_SETTING_KEYS, 415*9bb1b549SSpandan Das) 416*9bb1b549SSpandan Das 417*9bb1b549SSpandan Das# A list of Go build tags that potentially affect the build of the standard 418*9bb1b549SSpandan Das# library. 419*9bb1b549SSpandan Das# 420*9bb1b549SSpandan Das# This should be updated to contain the union of all tags relevant for all 421*9bb1b549SSpandan Das# versions of Go that are still relevant. 422*9bb1b549SSpandan Das# 423*9bb1b549SSpandan Das# Currently supported versions: 1.18, 1.19, 1.20 424*9bb1b549SSpandan Das# 425*9bb1b549SSpandan Das# To regenerate, run and paste the output of 426*9bb1b549SSpandan Das# bazel run //go/tools/internal/stdlib_tags:stdlib_tags -- path/to/go_sdk_1/src ... 427*9bb1b549SSpandan Das_TAG_AFFECTS_STDLIB = { 428*9bb1b549SSpandan Das "alpha": None, 429*9bb1b549SSpandan Das "appengine": None, 430*9bb1b549SSpandan Das "asan": None, 431*9bb1b549SSpandan Das "boringcrypto": None, 432*9bb1b549SSpandan Das "cmd_go_bootstrap": None, 433*9bb1b549SSpandan Das "compiler_bootstrap": None, 434*9bb1b549SSpandan Das "debuglog": None, 435*9bb1b549SSpandan Das "faketime": None, 436*9bb1b549SSpandan Das "gc": None, 437*9bb1b549SSpandan Das "gccgo": None, 438*9bb1b549SSpandan Das "gen": None, 439*9bb1b549SSpandan Das "generate": None, 440*9bb1b549SSpandan Das "gofuzz": None, 441*9bb1b549SSpandan Das "ignore": None, 442*9bb1b549SSpandan Das "libfuzzer": None, 443*9bb1b549SSpandan Das "m68k": None, 444*9bb1b549SSpandan Das "math_big_pure_go": None, 445*9bb1b549SSpandan Das "msan": None, 446*9bb1b549SSpandan Das "netcgo": None, 447*9bb1b549SSpandan Das "netgo": None, 448*9bb1b549SSpandan Das "nethttpomithttp2": None, 449*9bb1b549SSpandan Das "nios2": None, 450*9bb1b549SSpandan Das "noopt": None, 451*9bb1b549SSpandan Das "osusergo": None, 452*9bb1b549SSpandan Das "purego": None, 453*9bb1b549SSpandan Das "race": None, 454*9bb1b549SSpandan Das "sh": None, 455*9bb1b549SSpandan Das "shbe": None, 456*9bb1b549SSpandan Das "tablegen": None, 457*9bb1b549SSpandan Das "testgo": None, 458*9bb1b549SSpandan Das "timetzdata": None, 459*9bb1b549SSpandan Das} 460