diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/defs.bzl | 33 | ||||
-rwxr-xr-x | tools/go_branch.sh | 73 | ||||
-rw-r--r-- | tools/go_generics/go_merge/BUILD | 3 | ||||
-rw-r--r-- | tools/go_generics/go_merge/main.go | 19 |
4 files changed, 99 insertions, 29 deletions
diff --git a/tools/defs.bzl b/tools/defs.bzl index 4be767432..d2c697c0d 100644 --- a/tools/defs.bzl +++ b/tools/defs.bzl @@ -10,7 +10,7 @@ load("//tools/go_marshal:defs.bzl", "go_marshal", "marshal_deps", "marshal_test_ load("//tools/nogo:defs.bzl", "nogo_test") load("//tools/bazeldefs:defs.bzl", _arch_genrule = "arch_genrule", _build_test = "build_test", _bzl_library = "bzl_library", _coreutil = "coreutil", _default_installer = "default_installer", _default_net_util = "default_net_util", _more_shards = "more_shards", _most_shards = "most_shards", _proto_library = "proto_library", _select_arch = "select_arch", _select_system = "select_system", _short_path = "short_path", _version = "version") load("//tools/bazeldefs:cc.bzl", _cc_binary = "cc_binary", _cc_flags_supplier = "cc_flags_supplier", _cc_grpc_library = "cc_grpc_library", _cc_library = "cc_library", _cc_proto_library = "cc_proto_library", _cc_test = "cc_test", _cc_toolchain = "cc_toolchain", _gbenchmark = "gbenchmark", _grpcpp = "grpcpp", _gtest = "gtest", _vdso_linker_option = "vdso_linker_option") -load("//tools/bazeldefs:go.bzl", _gazelle = "gazelle", _go_binary = "go_binary", _go_embed_data = "go_embed_data", _go_grpc_and_proto_libraries = "go_grpc_and_proto_libraries", _go_library = "go_library", _go_path = "go_path", _go_proto_library = "go_proto_library", _go_test = "go_test", _select_goarch = "select_goarch", _select_goos = "select_goos") +load("//tools/bazeldefs:go.bzl", _gazelle = "gazelle", _go_binary = "go_binary", _go_embed_data = "go_embed_data", _go_grpc_and_proto_libraries = "go_grpc_and_proto_libraries", _go_library = "go_library", _go_path = "go_path", _go_proto_library = "go_proto_library", _go_rule = "go_rule", _go_test = "go_test", _select_goarch = "select_goarch", _select_goos = "select_goos") load("//tools/bazeldefs:pkg.bzl", _pkg_deb = "pkg_deb", _pkg_tar = "pkg_tar") load("//tools/bazeldefs:platforms.bzl", _default_platform = "default_platform", _platforms = "platforms") load("//tools/bazeldefs:tags.bzl", "go_suffixes") @@ -43,10 +43,10 @@ vdso_linker_option = _vdso_linker_option # Go rules. gazelle = _gazelle -go_embed_data = _go_embed_data go_path = _go_path select_goos = _select_goos select_goarch = _select_goarch +go_embed_data = _go_embed_data # Packaging rules. pkg_deb = _pkg_deb @@ -56,6 +56,35 @@ pkg_tar = _pkg_tar default_platform = _default_platform platforms = _platforms +def _go_add_tags(ctx): + """ Adds tags to the given source file. """ + output = ctx.outputs.out + runner = ctx.actions.declare_file(ctx.label.name + ".sh") + lines = ["#!/bin/bash"] + lines += ["echo '// +build %s' >> %s" % (tag, output.path) for tag in ctx.attr.go_tags] + lines.append("echo '' >> %s" % output.path) + lines += ["cat %s >> %s" % (f.path, output.path) for f in ctx.files.src] + lines.append("") + ctx.actions.write(runner, "\n".join(lines), is_executable = True) + ctx.actions.run( + inputs = ctx.files.src, + outputs = [output], + executable = runner, + ) + return [DefaultInfo( + files = depset([output]), + )] + +go_add_tags = _go_rule( + rule, + implementation = _go_add_tags, + attrs = { + "go_tags": attr.string_list(doc = "Go build tags to be added.", mandatory = True), + "src": attr.label(doc = "Source file.", allow_single_file = True, mandatory = True), + "out": attr.output(doc = "Output file.", mandatory = True), + }, +) + def go_binary(name, nogo = True, pure = False, static = False, x_defs = None, **kwargs): """Wraps the standard go_binary. diff --git a/tools/go_branch.sh b/tools/go_branch.sh index 7ef4ddf83..3a6a83f2e 100755 --- a/tools/go_branch.sh +++ b/tools/go_branch.sh @@ -16,23 +16,6 @@ set -xeou pipefail -# Discovery the package name from the go.mod file. -declare module origpwd othersrc -module=$(cat go.mod | grep -E "^module" | cut -d' ' -f2) -origpwd=$(pwd) -othersrc=("go.mod" "go.sum" "AUTHORS" "LICENSE") -readonly module origpwd othersrc - - -# Check that gopath has been built. -declare gopath_dir -gopath_dir="$(pwd)/bazel-bin/gopath/src/${module}" -readonly gopath_dir -if ! [[ -d "${gopath_dir}" ]]; then - echo "No gopath directory found; build the :gopath target." >&2 - exit 1 -fi - # Create a temporary working directory, and ensure that this directory and all # subdirectories are cleaned up upon exit. declare tmp_dir @@ -44,6 +27,51 @@ finish() { } trap finish EXIT +# Discover the package name from the go.mod file. +declare module origpwd othersrc +module=$(cat go.mod | grep -E "^module" | cut -d' ' -f2) +origpwd=$(pwd) +othersrc=("go.mod" "go.sum" "AUTHORS" "LICENSE") +readonly module origpwd othersrc + +# Build an amd64 & arm64 gopath. +declare -r go_amd64="${tmp_dir}/amd64" +declare -r go_arm64="${tmp_dir}/arm64" +rm -rf bazel-bin/gopath +make build BAZEL_OPTIONS="" TARGETS="//:gopath" +rsync --recursive --delete --copy-links bazel-bin/gopath/ "${go_amd64}" +rm -rf bazel-bin/gopath +make build BAZEL_OPTIONS=--config=cross-aarch64 TARGETS="//:gopath" +rsync --recursive --delete --copy-links bazel-bin/gopath/ "${go_arm64}" + +# Strip irrelevant files, i.e. use only arm64 files from the arm64 build. +# This is because bazel may generate incorrect files for non-target platforms +# as a workaround. See pkg/sentry/loader/vdsodata as an example. +find "${go_amd64}/src/${module}" -name '*_arm64*.go' -exec rm -f {} \; +find "${go_amd64}/src/${module}" -name '*_arm64*.s' -exec rm -f {} \; +find "${go_arm64}/src/${module}" -name '*_amd64*.go' -exec rm -f {} \; +find "${go_arm64}/src/${module}" -name '*_amd64*.s' -exec rm -f {} \; + +# See below. The certs.go file is pseudo-random, and therefore will also +# differ between the branches. Since we merge, it only has to come from one. +# We arbitrarily keep the one from the amd64 branch, and drop the arm64 one. +rm -f "${go_arm64}/src/${module}/webhook/pkg/injector/certs.go" + +# Check that all files are compatible. This means that if the files exist in +# both architectures, then they must be identical. The only ones that we expect +# to exist in a single architecture (due to binary builds) may be different. +function cross_check() { + (cd "${1}" && find "src/${module}" -type f | \ + xargs -n 1 -I {} sh -c "diff '${1}/{}' '${2}/{}' 2>/dev/null; test \$? -ne 1") +} +cross_check "${go_arm64}" "${go_amd64}" +cross_check "${go_amd64}" "${go_arm64}" + +# Merge the two for a complete set of source files. +declare -r go_merged="${tmp_dir}/merged" +rsync --recursive --update "${go_amd64}/" "${go_merged}" +rsync --recursive --update "${go_arm64}/" "${go_merged}" + # Record the current working commit. declare head head=$(git describe --always) @@ -89,14 +117,15 @@ git merge --no-commit --strategy ours "${head}" || \ find . -type f -exec chmod 0644 {} \; find . -type d -exec chmod 0755 {} \; -# Sync the entire gopath_dir. Note that we exclude auto-generated source -# files that will change here. Otherwise, it adds a tremendous amount of noise -# to commits. If this file disappears in the future, then presumably we will -# still delete the underlying directory. +# Sync the entire gopath. Note that we exclude auto-generated source files that +# will change here. Otherwise, it adds a tremendous amount of noise to commits. +# If this file disappears in the future, then presumably we will still delete +# the underlying directory. +declare -r gopath="${go_merged}/src/${module}" rsync --recursive --delete \ --exclude .git \ --exclude webhook/pkg/injector/certs.go \ - -L "${gopath_dir}/" . + "${gopath}/" . # Add additional files. for file in "${othersrc[@]}"; do diff --git a/tools/go_generics/go_merge/BUILD b/tools/go_generics/go_merge/BUILD index 2fd5a200d..5e0487e93 100644 --- a/tools/go_generics/go_merge/BUILD +++ b/tools/go_generics/go_merge/BUILD @@ -6,4 +6,7 @@ go_binary( name = "go_merge", srcs = ["main.go"], visibility = ["//:sandbox"], + deps = [ + "//tools/tags", + ], ) diff --git a/tools/go_generics/go_merge/main.go b/tools/go_generics/go_merge/main.go index e0345500f..801f2354f 100644 --- a/tools/go_generics/go_merge/main.go +++ b/tools/go_generics/go_merge/main.go @@ -22,10 +22,12 @@ import ( "go/format" "go/parser" "go/token" - "io/ioutil" "os" "path/filepath" "strconv" + "strings" + + "gvisor.dev/gvisor/tools/tags" ) var ( @@ -132,10 +134,17 @@ func main() { // Write the output file. var buf bytes.Buffer if err := format.Node(&buf, fset, f); err != nil { - fatalf("%v\n", err) + fatalf("fomatting: %v\n", err) } - - if err := ioutil.WriteFile(*output, buf.Bytes(), 0644); err != nil { - fatalf("%v\n", err) + outf, err := os.OpenFile(*output, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) + if err != nil { + fatalf("opening output: %v\n", err) + } + defer outf.Close() + if t := tags.Aggregate(flag.Args()); len(t) > 0 { + fmt.Fprintf(outf, "%s\n\n", strings.Join(t.Lines(), "\n")) + } + if _, err := outf.Write(buf.Bytes()); err != nil { + fatalf("write: %v\n", err) } } |