From 80b5a0f2c44a0ccb256bceb922b11c25ff14b380 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Thu, 8 Dec 2022 14:35:23 +0000 Subject: [PATCH 1/5] Make C++ toolchain optional Currently, if you transition a go_binary, you must have a C++ toolchain for it even if it's building in pure mode without cgo. By making this toolchain optional, we push the error from a toolchain-resolution-time error to an analysis-time error only if a toolchain is both _needed_ and not found. --- go/private/context.bzl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go/private/context.bzl b/go/private/context.bzl index ab278fa2e0..0230aa0411 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -838,7 +838,13 @@ cgo_context_data = rule( default = "@bazel_tools//tools/osx:current_xcode_config", ), }, - toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], + toolchains = [ + # In pure mode, a C++ toolchain isn't needed when transitioning. + # But if we declare a mandatory toolchain dependency here, a cross-compiling C++ toolchain is required at toolchain resolution time. + # So we make this toolchain dependency optional, so that it's only attempted to be looked up if it's actually needed. + # Optional toolchain support was added in bazel 6.0.0. + config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False) if hasattr(config_common, "toolchain_type") else "@bazel_tools//tools/cpp:toolchain_type", + ], fragments = ["apple", "cpp"], doc = """Collects information about the C/C++ toolchain. The C/C++ toolchain is needed to build cgo code, but is generally optional. Rules can't have From 1971a0ad72efaf4241229377142992fc6eeb8d3f Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Thu, 8 Dec 2022 16:45:15 +0000 Subject: [PATCH 2/5] Add tests --- .bazelci/presubmit.yml | 19 +++++++++++++++++++ tests/core/cross/BUILD.bazel | 24 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 85b7fece71..4bc3203639 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -14,6 +14,10 @@ tasks: - tests/core/cgo/generate_imported_dylib.sh build_targets: - "//..." + - "--" + - "-//tests/core/cross:darwin_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:linux_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:windows_go_cross_cgo" # Doesn't work before bazel 6 test_targets: - "//..." # Bzlmod tests require Bazel 6+ @@ -28,6 +32,10 @@ tasks: - "--config=incompatible" build_targets: - "//..." + - "--" + - "-//tests/core/cross:darwin_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:linux_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:windows_go_cross_cgo" # Doesn't work before bazel 6 test_targets: - "//..." debian11_zig_cc: @@ -67,6 +75,10 @@ tasks: - "--host_crosstool_top=@local_config_apple_cc//:toolchain" build_targets: - "//..." + - "--" + - "-//tests/core/cross:darwin_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:linux_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:windows_go_cross_cgo" # Doesn't work before bazel 6 test_flags: - "--apple_crosstool_top=@local_config_apple_cc//:toolchain" - "--crosstool_top=@local_config_apple_cc//:toolchain" @@ -78,6 +90,10 @@ tasks: - tests/core/cgo/generate_imported_dylib.sh build_targets: - "//..." + - "--" + - "-//tests/core/cross:darwin_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:linux_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:windows_go_cross_cgo" # Doesn't work before bazel 6 test_flags: # Some tests depend on this feature being disabled. However, because it's # enabled by default in the rbe_ubuntu1604 platform, we cannot simply remove @@ -243,6 +259,9 @@ tasks: - "-//tests/legacy/test_chdir:go_default_test" - "-//tests/legacy/test_rundir:go_default_test" - "-//tests/legacy/transitive_data:go_default_test" + - "-//tests/core/cross:darwin_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:linux_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:windows_go_cross_cgo" # Doesn't work before bazel 6 test_flags: - '--action_env=PATH=C:\tools\msys64\usr\bin;C:\tools\msys64\bin;C:\tools\msys64\mingw64\bin;C:\python3\Scripts\;C:\python3;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Windows\System32\OpenSSH;C:\ProgramData\GooGet;C:\Program Files\Google\Compute Engine\metadata_scripts;C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\bin;C:\Program Files\Google\Compute Engine\sysprep;C:\ProgramData\chocolatey\bin;C:\Program Files\Git\cmd;C:\tools\msys64\usr\bin;c:\openjdk\bin;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\CMake\bin;c:\ninja;c:\bazel;c:\buildkite' # On Windows CI, bazel (bazelisk) needs %LocalAppData% to find the cache directory. diff --git a/tests/core/cross/BUILD.bazel b/tests/core/cross/BUILD.bazel index ec1799847c..44edfc8294 100644 --- a/tests/core/cross/BUILD.bazel +++ b/tests/core/cross/BUILD.bazel @@ -66,6 +66,30 @@ go_cross_binary( target = ":native_bin", ) +# Because pure = "on" on the underlying target, this doesn't actually need cgo (and won't try to use it). +# This target ensures that (from Bazel 6) we don't require a C++ toolchain if we're not actually going to use cgo. +go_cross_binary( + name = "windows_go_cross_cgo", + platform = "@io_bazel_rules_go//go/toolchain:windows_amd64_cgo", + target = ":native_bin", +) + +# Because pure = "on" on the underlying target, this doesn't actually need cgo (and won't try to use it). +# This target ensures that (from Bazel 6) we don't require a C++ toolchain if we're not actually going to use cgo. +go_cross_binary( + name = "linux_go_cross_cgo", + platform = "@io_bazel_rules_go//go/toolchain:linux_amd64_cgo", + target = ":native_bin", +) + +# Because pure = "on" on the underlying target, this doesn't actually need cgo (and won't try to use it). +# This target ensures that (from Bazel 6) we don't require a C++ toolchain if we're not actually going to use cgo. +go_cross_binary( + name = "darwin_go_cross_cgo", + platform = "@io_bazel_rules_go//go/toolchain:darwin_amd64_cgo", + target = ":native_bin", +) + go_library( name = "platform_lib", srcs = select({ From 59a24d272015c37a261978f86204a30523fb046f Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Thu, 8 Dec 2022 17:06:50 +0000 Subject: [PATCH 3/5] Add target that actually uses cgo --- tests/core/cross/BUILD.bazel | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/core/cross/BUILD.bazel b/tests/core/cross/BUILD.bazel index 44edfc8294..a436b659ee 100644 --- a/tests/core/cross/BUILD.bazel +++ b/tests/core/cross/BUILD.bazel @@ -24,6 +24,21 @@ go_binary( deps = [":platform_lib"], ) +go_binary( + name = "linux_cross_impure", + srcs = ["main.go"], + goarch = "amd64", + goos = "linux", + pure = "off", + deps = [":platform_lib"], +) + +go_cross_binary( + name = "linux_go_cross_impure_cgo", + platform = "@io_bazel_rules_go//go/toolchain:linux_amd64_cgo", + target = ":linux_cross_impure", +) + go_binary( name = "darwin_cross", srcs = ["main.go"], From a3d516db59b90314145c114dc4599f1710d8b404 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 22 Dec 2023 16:04:21 +0000 Subject: [PATCH 4/5] Switch to use bazel_features Also switch from @bazel_tools//tools/cpp:current_cc_toolchain to @bazel_tools//tools/cpp:optional_current_cc_toolchain because otherwise we still get a hard error if the toolchain can't be found. --- go/private/BUILD.bazel | 1 + go/private/context.bzl | 13 +++++++---- go/private/fake_bazel_features.bzl | 35 ++++++++++++++++++++++++++++++ go/private/repositories.bzl | 6 +++++ 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 go/private/fake_bazel_features.bzl diff --git a/go/private/BUILD.bazel b/go/private/BUILD.bazel index 6af09aa55f..af6f7bb6cc 100644 --- a/go/private/BUILD.bazel +++ b/go/private/BUILD.bazel @@ -60,6 +60,7 @@ bzl_library( "//go/platform:apple", "//go/private:go_toolchain", "//go/private/rules:transition", + "@bazel_features//:features.bzl", "@bazel_skylib//lib:paths", "@bazel_skylib//rules:common_settings", "@bazel_tools//tools/build_defs/cc:action_names.bzl", diff --git a/go/private/context.bzl b/go/private/context.bzl index 0230aa0411..78d119023c 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@bazel_features//:features.bzl", "bazel_features") load( "@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", @@ -643,8 +644,12 @@ def _cgo_context_data_impl(ctx): # toolchain (to be inputs into actions that need it). # ctx.files._cc_toolchain won't work when cc toolchain resolution # is switched on. - cc_toolchain = find_cpp_toolchain(ctx) - if cc_toolchain.compiler in _UNSUPPORTED_C_COMPILERS: + find_cpp_toolchain_kwargs = {} + if bazel_features.cc.find_cpp_toolchain_has_mandatory_param: + find_cpp_toolchain_kwargs["mandatory"] = False + + cc_toolchain = find_cpp_toolchain(ctx, **find_cpp_toolchain_kwargs) + if not cc_toolchain or cc_toolchain.compiler in _UNSUPPORTED_C_COMPILERS: return [] feature_configuration = cc_common.configure_features( @@ -833,7 +838,7 @@ def _cgo_context_data_impl(ctx): cgo_context_data = rule( implementation = _cgo_context_data_impl, attrs = { - "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"), + "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:optional_current_cc_toolchain" if bazel_features.cc.find_cpp_toolchain_has_mandatory_param else "@bazel_tools//tools/cpp:current_cc_toolchain"), "_xcode_config": attr.label( default = "@bazel_tools//tools/osx:current_xcode_config", ), @@ -843,7 +848,7 @@ cgo_context_data = rule( # But if we declare a mandatory toolchain dependency here, a cross-compiling C++ toolchain is required at toolchain resolution time. # So we make this toolchain dependency optional, so that it's only attempted to be looked up if it's actually needed. # Optional toolchain support was added in bazel 6.0.0. - config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False) if hasattr(config_common, "toolchain_type") else "@bazel_tools//tools/cpp:toolchain_type", + config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False) if bazel_features.cc.find_cpp_toolchain_has_mandatory_param else "@bazel_tools//tools/cpp:toolchain_type", ], fragments = ["apple", "cpp"], doc = """Collects information about the C/C++ toolchain. The C/C++ toolchain diff --git a/go/private/fake_bazel_features.bzl b/go/private/fake_bazel_features.bzl new file mode 100644 index 0000000000..c633931d8b --- /dev/null +++ b/go/private/fake_bazel_features.bzl @@ -0,0 +1,35 @@ +# bazel_features when used from a WORKSPACE rather than bzlmod context requires a two-step set-up (loading bazel_features, then calling a function from inside it). +# rules_go only has one-step set-up, and it would be a breaking change to require a second step. +# Accordingly, we supply a fake implementation of bazel_features which is only used when using rules_go from a WORKSPACE file, +# to avoid complicating code in rules_go itself. +# We just implement the checks we've seen we actually need, and hope to delete this completely when we are in a pure-bzlmod world. + +_FAKE_BAZEL_FEATURES = """bazel_features = struct( + cc = struct( + find_cpp_toolchain_has_mandatory_param = {find_cpp_toolchain_has_mandatory_param}, + ) +) +""" + +def _fake_bazel_features_impl(rctx): + # An empty string is treated as a "dev version", which is greater than anything. + bazel_version = native.bazel_version or "999999.999999.999999" + version_parts = bazel_version.split(".") + if len(version_parts) != 3: + fail("invalid Bazel version '{}': got {} dot-separated segments, want 3".format(bazel_version, len(version_parts))) + major_version_int = int(version_parts[0]) + minor_version_int = int(version_parts[1]) + + find_cpp_toolchain_has_mandatory_param = major_version_int > 6 or (major_version_int == 6 and minor_version_int >= 1) + + rctx.file("BUILD.bazel", """exports_files(["features.bzl"]) +""") + rctx.file("features.bzl", _FAKE_BAZEL_FEATURES.format( + find_cpp_toolchain_has_mandatory_param = repr(find_cpp_toolchain_has_mandatory_param), + )) + +fake_bazel_features = repository_rule( + implementation = _fake_bazel_features_impl, + # Force reruns on server restarts to keep native.bazel_version up-to-date. + local = True, +) diff --git a/go/private/repositories.bzl b/go/private/repositories.bzl index c38adde632..4ce1187bdc 100644 --- a/go/private/repositories.bzl +++ b/go/private/repositories.bzl @@ -15,6 +15,7 @@ # Once nested repositories work, this file should cease to exist. load("//go/private:common.bzl", "MINIMUM_BAZEL_VERSION") +load("//go/private:fake_bazel_features.bzl", "fake_bazel_features") load("//go/private/skylib/lib:versions.bzl", "versions") load("//go/private:nogo.bzl", "DEFAULT_NOGO", "go_register_nogo") load("//proto:gogo.bzl", "gogo_special_proto") @@ -284,6 +285,11 @@ def go_rules_dependencies(force = False): nogo = DEFAULT_NOGO, ) + _maybe( + fake_bazel_features, + name = "bazel_features", + ) + def _maybe(repo_rule, name, **kwargs): if name not in native.existing_rules(): repo_rule(name = name, **kwargs) From ae4360284ee7f786ae20a282a08d18589fcccd28 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Wed, 27 Dec 2023 11:51:19 +0000 Subject: [PATCH 5/5] Review comments --- .bazelci/presubmit.yml | 5 +++ go/private/context.bzl | 9 ++-- go/private/mode.bzl | 2 + ...atures.bzl => polyfill_bazel_features.bzl} | 12 +++--- go/private/repositories.bzl | 4 +- tests/core/cross/BUILD.bazel | 15 ------- tests/core/starlark/cgo/BUILD.bazel | 25 +++++++++++ tests/core/starlark/cgo/cgo_test.bzl | 43 +++++++++++++++++++ 8 files changed, 87 insertions(+), 28 deletions(-) rename go/private/{fake_bazel_features.bzl => polyfill_bazel_features.bzl} (78%) create mode 100644 tests/core/starlark/cgo/BUILD.bazel create mode 100644 tests/core/starlark/cgo/cgo_test.bzl diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 4bc3203639..3282fedd7e 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -18,8 +18,13 @@ tasks: - "-//tests/core/cross:darwin_go_cross_cgo" # Doesn't work before bazel 6 - "-//tests/core/cross:linux_go_cross_cgo" # Doesn't work before bazel 6 - "-//tests/core/cross:windows_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/starlark/cgo/..." # Doesn't work before bazel 6 test_targets: - "//..." + - "-//tests/core/cross:darwin_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:linux_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/cross:windows_go_cross_cgo" # Doesn't work before bazel 6 + - "-//tests/core/starlark/cgo/..." # Doesn't work before bazel 6 # Bzlmod tests require Bazel 6+ - "-//tests/core/nogo/bzlmod/..." ubuntu2004: diff --git a/go/private/context.bzl b/go/private/context.bzl index 78d119023c..17bc118b0f 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -644,11 +644,10 @@ def _cgo_context_data_impl(ctx): # toolchain (to be inputs into actions that need it). # ctx.files._cc_toolchain won't work when cc toolchain resolution # is switched on. - find_cpp_toolchain_kwargs = {} if bazel_features.cc.find_cpp_toolchain_has_mandatory_param: - find_cpp_toolchain_kwargs["mandatory"] = False - - cc_toolchain = find_cpp_toolchain(ctx, **find_cpp_toolchain_kwargs) + cc_toolchain = find_cpp_toolchain(ctx, mandatory = False) + else: + cc_toolchain = find_cpp_toolchain(ctx) if not cc_toolchain or cc_toolchain.compiler in _UNSUPPORTED_C_COMPILERS: return [] @@ -848,7 +847,7 @@ cgo_context_data = rule( # But if we declare a mandatory toolchain dependency here, a cross-compiling C++ toolchain is required at toolchain resolution time. # So we make this toolchain dependency optional, so that it's only attempted to be looked up if it's actually needed. # Optional toolchain support was added in bazel 6.0.0. - config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False) if bazel_features.cc.find_cpp_toolchain_has_mandatory_param else "@bazel_tools//tools/cpp:toolchain_type", + config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False) if hasattr(config_common, "toolchain_type") else "@bazel_tools//tools/cpp:toolchain_type", ], fragments = ["apple", "cpp"], doc = """Collects information about the C/C++ toolchain. The C/C++ toolchain diff --git a/go/private/mode.bzl b/go/private/mode.bzl index e18964394e..af077021f2 100644 --- a/go/private/mode.bzl +++ b/go/private/mode.bzl @@ -78,6 +78,8 @@ def _ternary(*values): def get_mode(ctx, go_toolchain, cgo_context_info, go_config_info): static = _ternary(go_config_info.static if go_config_info else "off") + if getattr(ctx.attr, "pure", None) == "off" and not cgo_context_info: + fail("{} has pure explicitly set to off, but no C++ toolchain could be found for its platform".format(ctx.label)) pure = _ternary( "on" if not cgo_context_info else "auto", go_config_info.pure if go_config_info else "off", diff --git a/go/private/fake_bazel_features.bzl b/go/private/polyfill_bazel_features.bzl similarity index 78% rename from go/private/fake_bazel_features.bzl rename to go/private/polyfill_bazel_features.bzl index c633931d8b..ce67744743 100644 --- a/go/private/fake_bazel_features.bzl +++ b/go/private/polyfill_bazel_features.bzl @@ -1,17 +1,17 @@ # bazel_features when used from a WORKSPACE rather than bzlmod context requires a two-step set-up (loading bazel_features, then calling a function from inside it). # rules_go only has one-step set-up, and it would be a breaking change to require a second step. -# Accordingly, we supply a fake implementation of bazel_features which is only used when using rules_go from a WORKSPACE file, +# Accordingly, we supply a polyfill implementation of bazel_features which is only used when using rules_go from a WORKSPACE file, # to avoid complicating code in rules_go itself. # We just implement the checks we've seen we actually need, and hope to delete this completely when we are in a pure-bzlmod world. -_FAKE_BAZEL_FEATURES = """bazel_features = struct( +_POLYFILL_BAZEL_FEATURES = """bazel_features = struct( cc = struct( find_cpp_toolchain_has_mandatory_param = {find_cpp_toolchain_has_mandatory_param}, ) ) """ -def _fake_bazel_features_impl(rctx): +def _polyfill_bazel_features_impl(rctx): # An empty string is treated as a "dev version", which is greater than anything. bazel_version = native.bazel_version or "999999.999999.999999" version_parts = bazel_version.split(".") @@ -24,12 +24,12 @@ def _fake_bazel_features_impl(rctx): rctx.file("BUILD.bazel", """exports_files(["features.bzl"]) """) - rctx.file("features.bzl", _FAKE_BAZEL_FEATURES.format( + rctx.file("features.bzl", _POLYFILL_BAZEL_FEATURES.format( find_cpp_toolchain_has_mandatory_param = repr(find_cpp_toolchain_has_mandatory_param), )) -fake_bazel_features = repository_rule( - implementation = _fake_bazel_features_impl, +polyfill_bazel_features = repository_rule( + implementation = _polyfill_bazel_features_impl, # Force reruns on server restarts to keep native.bazel_version up-to-date. local = True, ) diff --git a/go/private/repositories.bzl b/go/private/repositories.bzl index 4ce1187bdc..b2a9ecc054 100644 --- a/go/private/repositories.bzl +++ b/go/private/repositories.bzl @@ -15,7 +15,7 @@ # Once nested repositories work, this file should cease to exist. load("//go/private:common.bzl", "MINIMUM_BAZEL_VERSION") -load("//go/private:fake_bazel_features.bzl", "fake_bazel_features") +load("//go/private:polyfill_bazel_features.bzl", "polyfill_bazel_features") load("//go/private/skylib/lib:versions.bzl", "versions") load("//go/private:nogo.bzl", "DEFAULT_NOGO", "go_register_nogo") load("//proto:gogo.bzl", "gogo_special_proto") @@ -286,7 +286,7 @@ def go_rules_dependencies(force = False): ) _maybe( - fake_bazel_features, + polyfill_bazel_features, name = "bazel_features", ) diff --git a/tests/core/cross/BUILD.bazel b/tests/core/cross/BUILD.bazel index a436b659ee..44edfc8294 100644 --- a/tests/core/cross/BUILD.bazel +++ b/tests/core/cross/BUILD.bazel @@ -24,21 +24,6 @@ go_binary( deps = [":platform_lib"], ) -go_binary( - name = "linux_cross_impure", - srcs = ["main.go"], - goarch = "amd64", - goos = "linux", - pure = "off", - deps = [":platform_lib"], -) - -go_cross_binary( - name = "linux_go_cross_impure_cgo", - platform = "@io_bazel_rules_go//go/toolchain:linux_amd64_cgo", - target = ":linux_cross_impure", -) - go_binary( name = "darwin_cross", srcs = ["main.go"], diff --git a/tests/core/starlark/cgo/BUILD.bazel b/tests/core/starlark/cgo/BUILD.bazel new file mode 100644 index 0000000000..92b2ff9fbb --- /dev/null +++ b/tests/core/starlark/cgo/BUILD.bazel @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go/private:common.bzl", "GO_TOOLCHAIN") +load(":cgo_test.bzl", "cgo_test_suite") + +constraint_value( + name = "os_does_not_exist", + constraint_setting = "@platforms//os:os", +) + +# Make a platform we know won't have a C++ toolchain registered for it. +platform( + name = "platform_has_no_cc_toolchain", + constraint_values = [":os_does_not_exist"], +) + +# Make a fake Go toolchain for this platform +toolchain( + name = "fake_go_toolchain", + target_compatible_with = [ + ":os_does_not_exist", + ], + toolchain = "@go_sdk//:go_linux_amd64-impl", + toolchain_type = GO_TOOLCHAIN, +) + +cgo_test_suite() diff --git a/tests/core/starlark/cgo/cgo_test.bzl b/tests/core/starlark/cgo/cgo_test.bzl new file mode 100644 index 0000000000..b56acccfcd --- /dev/null +++ b/tests/core/starlark/cgo/cgo_test.bzl @@ -0,0 +1,43 @@ +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_cross_binary") + +def _missing_cc_toolchain_explicit_pure_off_test(ctx): + env = analysistest.begin(ctx) + + asserts.expect_failure(env, "has pure explicitly set to off, but no C++ toolchain could be found for its platform") + + return analysistest.end(env) + +missing_cc_toolchain_explicit_pure_off_test = analysistest.make( + _missing_cc_toolchain_explicit_pure_off_test, + expect_failure = True, + config_settings = { + "//command_line_option:extra_toolchains": str(Label("//tests/core/starlark/cgo:fake_go_toolchain")), + }, +) + +def cgo_test_suite(): + go_binary( + name = "cross_impure", + srcs = ["main.go"], + pure = "off", + tags = ["manual"], + ) + + go_cross_binary( + name = "go_cross_impure_cgo", + platform = ":platform_has_no_cc_toolchain", + target = ":cross_impure", + tags = ["manual"], + ) + + missing_cc_toolchain_explicit_pure_off_test( + name = "missing_cc_toolchain_explicit_pure_off_test", + target_under_test = ":go_cross_impure_cgo", + ) + + """Creates the test targets and test suite for cgo.bzl tests.""" + native.test_suite( + name = "cgo_tests", + tests = [":missing_cc_toolchain_explicit_pure_off_test"], + )