Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Bazel to compile multiple platform target at once?

Tags:

bazel

compile single platform:

# BUILD
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
go_binary(
      name = 'example',
      srcs = glob(["src/*.go"]),
)

It can compile normally, but when I want to compile multiple platforms, only this way:

bazel build --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 //:example
bazel build --platforms=@io_bazel_rules_go//go/toolchain:linux_386 //:example
bazel build --platforms=@io_bazel_rules_go//go/toolchain:windows_amd64 //:example
bazel build --platforms=@io_bazel_rules_go//go/toolchain:darwin_amd64 //:example

I want compile multiple platform target on once,so I try this:

# BUILD
load("//:matrix.bzl", "build_all_platform")


build_all_platform(
    name = 'example',
    pkg = glob(["src/*.go"]),
)

# matrix.bzl
load("@io_bazel_rules_go//go:def.bzl", "go_binary")

SUPPORTED_MATRIX = [
  ("windows", "amd64"),
  ("darwin", "amd64"),
  ("linux", "amd64"),
  ("linux", "386"),
]

def _build(ctx):
    for goos, goarch in SUPPORTED_MATRIX:
        target_name = 'proxy-download-' + goos + '-' + goarch
        if goos == 'windows':
            target_name += '.exe'

        go_binary(
            name = target_name,
            srcs = ctx.attr.pkg,
            pure = "auto",
            goos = goos,
            goarch = goarch,
        )

build_all_platform = rule(
    _build,
     attrs = {
        'pkg': attr.string_list(),
      },
      executable = True,
)

But encountered an error, I think this may be the reason for rules_go.

Traceback (most recent call last):
    File "/source/proxy-download/BUILD", line 4
        build_all_platform(name = 'proxy-download')
    File "/source/proxy-download/matrix.bzl", line 16, in _build
        go_binary(name = target_name, <4 more arguments>)
    File "/private/var/tmp/_bazel_/071099b99a462d431baf96a3ef76cd28/external/io_bazel_rules_go/go/private/rules/wrappers.bzl", line 50, in go_binary
        go_transition_wrapper(go_binary, <3 more arguments>)
    File "/private/var/tmp/_bazel_/071099b99a462d431baf96a3ef76cd28/external/io_bazel_rules_go/go/private/rules/transition.bzl", line 60, in go_transition_wrapper
        transition_kind(name = name, <1 more arguments>)
'rule' can only be called during the loading phase

Try to pass multiple platforms at the same time mentioned in this issue

bazel build --platforms=@io_bazel_rules_go//go/toolchain:linux_386,@io_bazel_rules_go//go/toolchain:linux_amd64 //:example

> WARNING: --platforms only supports a single target platform: using the first option @io_bazel_rules_go//go/toolchain:linux_386

For reference, this code implements this by using the build command line

options = [
    "go",
    "build",
    "-o", output_file.path,
    "-compiler", "gc",
    "-gcflags", '"all=-trimpath=${GOPATH}/src"',
    "-asmflags", '"all=-trimpath=${GOPATH}/src"',
    "-ldflags", "'%s'" % ld_flags,
    "-tags", "'%s'" % ctx.attr.gotags,
    pkg,
  ]
like image 313
Spirytus Rektyfikowany Avatar asked Sep 07 '25 09:09

Spirytus Rektyfikowany


1 Answers

You may want to take a look at Bazel's user defined transitions that can build dependencies using different build configurations. Note that it's an experimental feature and not all build parameters are configurable.

like image 152
ArtemB Avatar answered Sep 10 '25 04:09

ArtemB