diff --git a/BUILD.bazel b/BUILD.bazel index 60bf72eb8e..1b1f8a0139 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -135,6 +135,7 @@ go_config( "//go/private:is_strip_sometimes_fastbuild": True, "//conditions:default": False, }), + testbuildonly = "//go/config:testbuildonly", visibility = ["//visibility:public"], ) diff --git a/go/config/BUILD.bazel b/go/config/BUILD.bazel index a292fc9dcf..821cd5a93d 100644 --- a/go/config/BUILD.bazel +++ b/go/config/BUILD.bazel @@ -79,3 +79,9 @@ string_list_flag( build_setting_default = [], visibility = ["//visibility:public"], ) + +bool_flag( + name = "testbuildonly", + build_setting_default = False, + visibility = ["//visibility:public"], +) diff --git a/go/private/actions/link.bzl b/go/private/actions/link.bzl index e919e3db92..4cc861deba 100644 --- a/go/private/actions/link.bzl +++ b/go/private/actions/link.bzl @@ -75,6 +75,22 @@ def emit_link( if executable == None: fail("executable is a required parameter") + if go.mode.testbuildonly and executable.basename.endswith("_test"): + inputs_transitive = [ + archive.libs, archive.cgo_deps, + as_set(go.crosstool), + as_set(go.sdk.tools), + as_set(go.stdlib.libs), + ] + go.actions.run( + inputs = depset(direct = [go.sdk.package_list], transitive = inputs_transitive), + outputs = [executable], + mnemonic = "Touch", + executable = "/usr/bin/touch", + arguments = [executable.path], + ) + return + # Exclude -lstdc++ from link options. We don't want to link against it # unless we actually have some C++ code. _cgo_codegen will include it # in archives via CGO_LDFLAGS if it's needed. diff --git a/go/private/context.bzl b/go/private/context.bzl index db4fe09d43..8b428d3c94 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -836,6 +836,7 @@ def _go_config_impl(ctx): cover_format = ctx.attr.cover_format[BuildSettingInfo].value, gc_goopts = ctx.attr.gc_goopts[BuildSettingInfo].value, amd64 = ctx.attr.amd64, + testbuildonly = ctx.attr.testbuildonly[BuildSettingInfo].value, )] go_config = rule( @@ -884,6 +885,10 @@ go_config = rule( providers = [BuildSettingInfo], ), "amd64": attr.string(), + "testbuildonly": attr.label( + mandatory = True, + providers = [BuildSettingInfo], + ), }, provides = [GoConfigInfo], doc = """Collects information about build settings in the current diff --git a/go/private/mode.bzl b/go/private/mode.bzl index 83ccd045b5..c7487f4983 100644 --- a/go/private/mode.bzl +++ b/go/private/mode.bzl @@ -52,6 +52,8 @@ def mode_string(mode): result.append("debug") if mode.strip: result.append("stripped") + if mode.testbuildonly: + result.append("testbuildonly") if not result or not mode.link == LINKMODE_NORMAL: result.append(mode.link) if mode.gc_goopts: @@ -93,6 +95,7 @@ def get_mode(ctx, go_toolchain, cgo_context_info, go_config_info): goos = go_toolchain.default_goos if getattr(ctx.attr, "goos", "auto") == "auto" else ctx.attr.goos goarch = go_toolchain.default_goarch if getattr(ctx.attr, "goarch", "auto") == "auto" else ctx.attr.goarch gc_goopts = go_config_info.gc_goopts if go_config_info else [] + testbuildonly = go_config_info.testbuildonly if go_config_info else False # TODO(jayconrod): check for more invalid and contradictory settings. if pure and race: @@ -130,6 +133,7 @@ def get_mode(ctx, go_toolchain, cgo_context_info, go_config_info): cover_format = cover_format, amd64 = amd64, gc_goopts = gc_goopts, + testbuildonly = testbuildonly, ) def installsuffix(mode): diff --git a/go/private/rules/transition.bzl b/go/private/rules/transition.bzl index 4e87e30efe..17e8226aec 100644 --- a/go/private/rules/transition.bzl +++ b/go/private/rules/transition.bzl @@ -177,6 +177,7 @@ _common_reset_transition_dict = dict({ "//go/config:debug": False, "//go/config:linkmode": LINKMODE_NORMAL, "//go/config:tags": [], + "//go/config:testbuildonly": False, }, **{setting: "" for setting in _SETTING_KEY_TO_ORIGINAL_SETTING_KEY.values()}) _reset_transition_dict = dict(_common_reset_transition_dict, **{