From e0a7844e2cd9b1700f362752985a2ba3e15a638b Mon Sep 17 00:00:00 2001 From: Michael Podtserkovskii Date: Wed, 14 Aug 2024 15:51:31 -0700 Subject: [PATCH] New rule go_bootstrap_binary for making Go tools for buck Summary: > Produces a Go binary for use in prelude. Similar to `python_bootstrap_binary`. It doesn't depend on other Go rules and uses `go build` under the hood. CGo is disabled minimise dependencies. The main purpose is to build tools for Go toolchain, e.q. test-main-gen or embedcfg-gen. However it can be used for other rules as Go wrappers are faster than Python It also may be used for building third-party Go binaries Reviewed By: leoleovich Differential Revision: D59154803 fbshipit-source-id: c3cf5accfb671bd37db7175c553f4ed4a7dd3c66 --- prelude/decls/go_rules.bzl | 9 ++++++ prelude/go/go_bootstrap_binary.bzl | 45 ++++++++++++++++++++++++++++++ prelude/go/tools/BUCK.v2 | 5 +++- prelude/rules_impl.bzl | 8 +++++- 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 prelude/go/go_bootstrap_binary.bzl diff --git a/prelude/decls/go_rules.bzl b/prelude/decls/go_rules.bzl index d7100f5d9923..8f9c1a11caa1 100644 --- a/prelude/decls/go_rules.bzl +++ b/prelude/decls/go_rules.bzl @@ -521,9 +521,18 @@ prebuilt_go_library = prelude_rule( ), ) +go_bootstrap_binary = prelude_rule( + name = "go_bootstrap_binary", + attrs = ( + go_common.srcs_arg() | + {"entrypoints": attrs.list(attrs.string(), default = [], doc = """Package name or file names""")} + ), +) + go_rules = struct( cgo_library = cgo_library, go_binary = go_binary, + go_bootstrap_binary = go_bootstrap_binary, go_exported_library = go_exported_library, go_library = go_library, go_test = go_test, diff --git a/prelude/go/go_bootstrap_binary.bzl b/prelude/go/go_bootstrap_binary.bzl new file mode 100644 index 000000000000..64e46cd31cf3 --- /dev/null +++ b/prelude/go/go_bootstrap_binary.bzl @@ -0,0 +1,45 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under both the MIT license found in the +# LICENSE-MIT file in the root directory of this source tree and the Apache +# License, Version 2.0 found in the LICENSE-APACHE file in the root directory +# of this source tree. + +load(":toolchain.bzl", "GoToolchainInfo", "get_toolchain_env_vars") + +def go_bootstrap_binary_impl(ctx: AnalysisContext) -> list[Provider]: + """ + Produces a Go binary for use in prelude. Similar to `python_bootstrap_binary` + It doesn't depend on other Go rules and uses `go build` under the hood. + CGo is disabled minimise dependencies. + """ + go_toolchain = ctx.attrs._go_toolchain[GoToolchainInfo] + + target_is_win = go_toolchain.env_go_os == "windows" + exe_suffix = ".exe" if target_is_win else "" + output = ctx.actions.declare_output(ctx.label.name + exe_suffix) + + # Copy files, becode go:embed doesn't work with symlinks + srcs_dir = ctx.actions.copied_dir( + "__srcs_dir__", + {src.short_path: src for src in ctx.attrs.srcs}, + ) + + cmd = cmd_args([ + go_toolchain.go_wrapper, + go_toolchain.go, + ["--workdir", srcs_dir], + "build", + ["-o", cmd_args(output.as_output(), relative_to = srcs_dir)], + ctx.attrs.entrypoints, + ]) + + env = get_toolchain_env_vars(go_toolchain) + env["CGO_ENABLED"] = "0" + + ctx.actions.run(cmd, env = env, category = "go_bootstrap_binary") + + return [ + DefaultInfo(default_output = output), + RunInfo(args = [output]), + ] diff --git a/prelude/go/tools/BUCK.v2 b/prelude/go/tools/BUCK.v2 index 4c31770f4811..7c7eeced6e86 100644 --- a/prelude/go/tools/BUCK.v2 +++ b/prelude/go/tools/BUCK.v2 @@ -30,11 +30,14 @@ prelude.python_bootstrap_binary( visibility = ["PUBLIC"], ) -prelude.go_binary( +prelude.go_bootstrap_binary( name = "testmaingen", srcs = [ "testmaingen.go", ], + entrypoints = [ + "testmaingen.go", + ], visibility = [ "PUBLIC", ], diff --git a/prelude/rules_impl.bzl b/prelude/rules_impl.bzl index de7173126bd1..7178542ba1c3 100644 --- a/prelude/rules_impl.bzl +++ b/prelude/rules_impl.bzl @@ -23,6 +23,7 @@ load("@prelude//git:git_fetch.bzl", "git_fetch_impl") load("@prelude//go:cgo_library.bzl", "cgo_library_impl") load("@prelude//go:coverage.bzl", "GoCoverageMode") load("@prelude//go:go_binary.bzl", "go_binary_impl") +load("@prelude//go:go_bootstrap_binary.bzl", "go_bootstrap_binary_impl") load("@prelude//go:go_exported_library.bzl", "go_exported_library_impl") load("@prelude//go:go_library.bzl", "go_library_impl") load("@prelude//go:go_stdlib.bzl", "go_stdlib_impl") @@ -174,6 +175,7 @@ extra_implemented_rules = struct( #go cgo_library = cgo_library_impl, go_binary = go_binary_impl, + go_bootstrap_binary = go_bootstrap_binary_impl, go_exported_library = go_exported_library_impl, go_library = go_library_impl, go_test = go_test_impl, @@ -473,6 +475,10 @@ inlined_extra_attributes = { "_race": race_attr, "_tags": tags_attr, }, + "go_bootstrap_binary": { + "_exec_os_type": buck.exec_os_type_arg(), + "_go_toolchain": toolchains_common.go(), + }, "go_exported_library": { "embedcfg": attrs.option(attrs.source(allow_directory = False), default = None), "_asan": asan_attr, @@ -513,7 +519,7 @@ inlined_extra_attributes = { "_go_toolchain": toolchains_common.go(), "_race": race_attr, "_tags": tags_attr, - "_testmaingen": attrs.default_only(attrs.exec_dep(default = "prelude//go/tools:testmaingen")), + "_testmaingen": attrs.default_only(attrs.exec_dep(providers = [RunInfo], default = "prelude//go/tools:testmaingen")), }, # groovy