Skip to content

Commit

Permalink
Add go_binary out attribute for custom file names
Browse files Browse the repository at this point in the history
go_binary now has an "out" attribute which allows users to set the
output filename for the generated executable. When set, go_binary will
write this file without mode-specific directory prefixes, without
linkmode-specific prefixes, and without platform-specific extensions.

Fixes bazel-contrib#1239
  • Loading branch information
Jay Conrod committed Mar 20, 2018
1 parent 63cd14e commit 44d78de
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 23 deletions.
9 changes: 9 additions & 0 deletions go/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,15 @@ Attributes
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`out` | :type:`string` | :value:`""` |
+----------------------------+-----------------------------+---------------------------------------+
| Sets the output filename for the generated executable. When set, ``go_binary`` |
| will write this file without mode-specific directory prefixes, without |
| linkmode-specific prefixes like "lib", and without platform-specific suffixes |
| like ".exe". Note that without a mode-specific directory prefix, the |
| output file (but not its dependencies) will be invalidated in Bazel's cache |
| when changing configurations. |
+----------------------------+-----------------------------+---------------------------------------+

go_test
~~~~~~~
Expand Down
27 changes: 15 additions & 12 deletions go/private/actions/binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,27 @@ load(
)

def emit_binary(go,
name="",
name = "",
source = None,
gc_linkopts = [],
linkstamp=None,
version_file=None,
info_file=None):
linkstamp = None,
version_file = None,
info_file = None,
executable = None):
"""See go/toolchains.rst#binary for full documentation."""

if name == "": fail("name is a required parameter")
if name == "" and executable == None:
fail("either name or executable must be set")

archive = go.archive(go, source)
extension = go.exe_extension
if go.mode.link == LINKMODE_C_SHARED:
name = "lib" + name # shared libraries need a "lib" prefix in their name
extension = go.shared_extension
elif go.mode.link == LINKMODE_C_ARCHIVE:
extension = ARCHIVE_EXTENSION
executable = go.declare_file(go, name=name, ext=extension)
if not executable:
extension = go.exe_extension
if go.mode.link == LINKMODE_C_SHARED:
name = "lib" + name # shared libraries need a "lib" prefix in their name
extension = go.shared_extension
elif go.mode.link == LINKMODE_C_ARCHIVE:
extension = ARCHIVE_EXTENSION
executable = go.declare_file(go, name=name, ext=extension)
go.link(go,
archive=archive,
executable=executable,
Expand Down
15 changes: 12 additions & 3 deletions go/private/rules/binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,20 @@ def _go_binary_impl(ctx):
name = ctx.attr.basename
if not name:
name = ctx.label.name
executable = None
if ctx.attr.out:
# Use declare_file instead of attr.output(). When users set output files
# directly, Bazel warns them not to use the same name as the rule, which is
# the common case with go_binary.
executable = ctx.actions.declare_file(ctx.attr.out)
archive, executable = go.binary(go,
name = name,
source = source,
gc_linkopts = gc_linkopts(ctx),
linkstamp=ctx.attr.linkstamp,
version_file=ctx.version_file,
info_file=ctx.info_file,
linkstamp = ctx.attr.linkstamp,
version_file = ctx.version_file,
info_file = ctx.info_file,
executable = executable,
)
return [
library, source, archive,
Expand Down Expand Up @@ -140,6 +147,7 @@ go_binary = go_rule(
"linkstamp": attr.string(),
"x_defs": attr.string_dict(),
"linkmode": attr.string(values=LINKMODES, default=LINKMODE_NORMAL),
"out": attr.string(),
},
executable = True,
)
Expand All @@ -162,6 +170,7 @@ go_tool_binary = go_rule(
"linkstamp": attr.string(),
"x_defs": attr.string_dict(),
"linkmode": attr.string(values=LINKMODES, default=LINKMODE_NORMAL),
"out": attr.string(),
"_hostonly": attr.bool(default=True),
},
executable = True,
Expand Down
29 changes: 21 additions & 8 deletions go/toolchains.rst
Original file line number Diff line number Diff line change
Expand Up @@ -559,9 +559,10 @@ binary
~~~~~~

This emits actions to compile and link Go code into a binary.
It supports embedding, cgo dependencies, coverage, and assembling and packing .s files.
It supports embedding, cgo dependencies, coverage, and assembling and packing
.s files.

It returns GoLibrary_.
It returns a tuple containing GoArchive_ and the output executable file.

+--------------------------------+-----------------------------+-----------------------------------+
| **Name** | **Type** | **Default value** |
Expand All @@ -570,23 +571,35 @@ It returns GoLibrary_.
+--------------------------------+-----------------------------+-----------------------------------+
| This must be the same GoContext object you got this function from. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`name` | :type:`string` | |mandatory| |
| :param:`name` | :type:`string` | :value:`""` |
+--------------------------------+-----------------------------+-----------------------------------+
| The base name of the generated binaries. |
| The base name of the generated binaries. Required if :param:`executable` is not given. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`source` | :type:`GoSource` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
| The GoSource_ that should be compiled and linked. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`gc_linkopts` | :type:`string_list` | :value:`[]` |
+--------------------------------+-----------------------------+-----------------------------------+
| Basic link options. |
| Go link options. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`x_defs` | :type:`map` | :value:`{}` |
| :param:`linkstamp` | :type:`string` | :value:`None` |
+--------------------------------+-----------------------------+-----------------------------------+
| Link defines, including build stamping ones. |
| Optional link stamp. See link_. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`version_file` | :type:`File` | :value:`None` |
+--------------------------------+-----------------------------+-----------------------------------+
| Version file used for link stamping. See link_. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`info_file` | :type:`File` | :value:`None` |
+--------------------------------+-----------------------------+-----------------------------------+
| Info file used for link stamping. See link_. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`executable` | :type:`File` | :value:`None` |
+--------------------------------+-----------------------------+-----------------------------------+
| Optional output file to write. If not set, ``binary`` will generate an output |
| file name based on ``name``, the target platform, and the link mode. |
+--------------------------------+-----------------------------+-----------------------------------+


compile
~~~~~~~
Expand Down
15 changes: 15 additions & 0 deletions tests/core/go_binary/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_test")

test_suite(name = "go_binary")

go_test(
name = "go_default_test",
srcs = ["out_test.go"],
data = [":custom_bin"],
)

go_binary(
name = "custom_bin",
srcs = ["custom_bin.go"],
out = "alt_bin",
)
12 changes: 12 additions & 0 deletions tests/core/go_binary/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Basic go_binary functionality
=============================

.. _go_binary: /go/core.rst#_go_binary

Tests to ensure the basic features of go_binary are working as expected.

out_test
--------

Test that a go_binary_ rule can write its executable file with a custom name
in the package directory (not the mode directory).
4 changes: 4 additions & 0 deletions tests/core/go_binary/custom_bin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package main

func main() {
}
13 changes: 13 additions & 0 deletions tests/core/go_binary/out_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main

import (
"os"
"testing"
)

func TestCustomBinaryName(t *testing.T) {
_, err := os.Stat("alt_bin")
if err != nil {
t.Error(err)
}
}

0 comments on commit 44d78de

Please sign in to comment.