title: How to use Bazel to compile multiple platform target at once?
body: <p>compile single platform:</p>
  
  <pre><code># BUILD
  load("@io_bazel_rules_go//go:def.bzl", "go_binary")
  go_binary(
        name = 'example',
        srcs = glob(["src/*.go"]),
  )
  </code></pre>
  
  <p>It can compile normally, but when I want to compile multiple platforms, only this way:</p>
  
  <pre class="lang-sh prettyprint-override"><code>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
  </code></pre>
  
  <p>I want compile multiple platform target on once,so I try this:</p>
  
  <pre><code># 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,
  )
  
  </code></pre>
  
  <p>But encountered an error, I think this may be the reason for <code>rules_go</code>.</p>
  
  <pre><code>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, &lt;4 more arguments&gt;)
      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, &lt;3 more arguments&gt;)
      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, &lt;1 more arguments&gt;)
  'rule' can only be called during the loading phase
  </code></pre>
  
  <p>Try to pass multiple platforms at the same time mentioned in <a href="https://github.com/bazelbuild/rules_go/issues/1952" rel="nofollow noreferrer">this issue</a></p>
  
  <pre><code>bazel build --platforms=@io_bazel_rules_go//go/toolchain:linux_386,@io_bazel_rules_go//go/toolchain:linux_amd64 //:example
  
  &gt; WARNING: --platforms only supports a single target platform: using the first option @io_bazel_rules_go//go/toolchain:linux_386
  </code></pre>
  
  <p>For reference, <a href="https://github.com/v2ray/v2ray-core/blob/master/infra/bazel/build.bzl" rel="nofollow noreferrer">this code</a> implements this by using the build command line</p>
  
  <pre class="lang-py prettyprint-override"><code>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,
    ]
  </code></pre>