Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support gc_goopts and gc_linkopts attributes #291

Merged
merged 1 commit into from
Mar 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 70 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ go_prefix(prefix)
## go\_library

```bzl
go_library(name, srcs, deps, data)
go_library(name, srcs, deps, data, gc_goopts)
```
<table class="table table-condensed table-bordered table-params">
<colgroup>
Expand Down Expand Up @@ -357,14 +357,25 @@ go_library(name, srcs, deps, data)
<p>List of files needed by this rule at runtime.</p>
</td>
</tr>
<tr>
<td><code>gc_goopts</code></td>
<td>
<code>List of strings, optional</code>
<p>List of flags to add to the Go compilation command. Subject to
<a href="https://bazel.build/versions/master/docs/be/make-variables.html#make-var-substitution">Make
variable substitution</a> and
<a href="https://bazel.build/versions/master/docs/be/common-definitions.html#sh-tokenization">Bourne
shell tokenization</a>.</p>
</td>
</tr>
</tbody>
</table>

<a name="cgo_library"></a>
## cgo\_library

```bzl
cgo_library(name, srcs, copts, clinkopts, cdeps, deps, data)
cgo_library(name, srcs, copts, clinkopts, cdeps, deps, data, gc_goopts)
```
<table class="table table-condensed table-bordered table-params">
<colgroup>
Expand Down Expand Up @@ -431,6 +442,17 @@ cgo_library(name, srcs, copts, clinkopts, cdeps, deps, data)
<p>List of files needed by this rule at runtime.</p>
</td>
</tr>
<tr>
<td><code>gc_goopts</code></td>
<td>
<code>List of strings, optional</code>
<p>List of flags to add to the Go compilation command. Subject to
<a href="https://bazel.build/versions/master/docs/be/make-variables.html#make-var-substitution">Make
variable substitution</a> and
<a href="https://bazel.build/versions/master/docs/be/common-definitions.html#sh-tokenization">Bourne
shell tokenization</a>.</p>
</td>
</tr>
</tbody>
</table>

Expand All @@ -457,7 +479,7 @@ go_library(
## go\_binary

```bzl
go_binary(name, srcs, deps, data, linkstamp)
go_binary(name, srcs, deps, data, linkstamp, gc_goopts, gc_linkopts)
```
<table class="table table-condensed table-bordered table-params">
<colgroup>
Expand Down Expand Up @@ -516,14 +538,36 @@ go_binary(name, srcs, deps, data, linkstamp)
a good template which prints Git workspace status.</p>
</td>
</tr>
<tr>
<td><code>gc_goopts</code></td>
<td>
<code>List of strings, optional</code>
<p>List of flags to add to the Go compilation command. Subject to
<a href="https://bazel.build/versions/master/docs/be/make-variables.html#make-var-substitution">Make
variable substitution</a> and
<a href="https://bazel.build/versions/master/docs/be/common-definitions.html#sh-tokenization">Bourne
shell tokenization</a>.</p>
</td>
</tr>
<tr>
<td><code>gc_linkopts</code></td>
<td>
<code>List of strings, optional</code>
<p>List of flags to add to the Go link command. Subject to
<a href="https://bazel.build/versions/master/docs/be/make-variables.html#make-var-substitution">Make
variable substitution</a> and
<a href="https://bazel.build/versions/master/docs/be/common-definitions.html#sh-tokenization">Bourne
shell tokenization</a>.</p>
</td>
</tr>
</tbody>
</table>

<a name="go_test"></a>
## go\_test

```bzl
go_test(name, srcs, deps, data)
go_test(name, srcs, deps, data, gc_goopts, gc_linkopts)
```
<table class="table table-condensed table-bordered table-params">
<colgroup>
Expand Down Expand Up @@ -565,6 +609,28 @@ go_test(name, srcs, deps, data)
<p>List of files needed by this rule at runtime.</p>
</td>
</tr>
<tr>
<td><code>gc_goopts</code></td>
<td>
<code>List of strings, optional</code>
<p>List of flags to add to the Go compilation command. Subject to
<a href="https://bazel.build/versions/master/docs/be/make-variables.html#make-var-substitution">Make
variable substitution</a> and
<a href="https://bazel.build/versions/master/docs/be/common-definitions.html#sh-tokenization">Bourne
shell tokenization</a>.</p>
</td>
</tr>
<tr>
<td><code>gc_linkopts</code></td>
<td>
<code>List of strings, optional</code>
<p>List of flags to add to the Go link command. Subject to
<a href="https://bazel.build/versions/master/docs/be/make-variables.html#make-var-substitution">Make
variable substitution</a> and
<a href="https://bazel.build/versions/master/docs/be/common-definitions.html#sh-tokenization">Bourne
shell tokenization</a>.</p>
</td>
</tr>
</tbody>
</table>

Expand Down
73 changes: 47 additions & 26 deletions go/def.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ def _is_external(p):
"""Checks if the string starts with ../"""
return p[0:3] == '../'

def emit_go_compile_action(ctx, sources, deps, out_lib, extra_objects=[]):
def _emit_go_compile_action(ctx, sources, deps, out_lib,
extra_objects, gc_goopts):
"""Construct the command line for compiling Go code.
Constructs a symlink tree to accommodate for workspace name.

Expand All @@ -218,6 +219,7 @@ def emit_go_compile_action(ctx, sources, deps, out_lib, extra_objects=[]):
out_lib: the artifact (configured target?) that should be produced
extra_objects: an iterable of extra object files to be added to the
output archive file.
gc_goopts: additional flags to pass to the compiler.
"""
tree_layout = {}
inputs = []
Expand All @@ -243,7 +245,7 @@ def emit_go_compile_action(ctx, sources, deps, out_lib, extra_objects=[]):
"tool", "compile",
"-o", ('../' * out_depth) + out_lib.path, "-pack",
"-I", "."
]
] + gc_goopts

# Set -p to the import path of the library, ie.
# (ctx.label.package + "/" ctx.label.name) for now.
Expand Down Expand Up @@ -288,7 +290,6 @@ def go_library_impl(ctx):
"already has cgo_object in %s" % (ctx.label.name,
ctx.attr.library.name))
cgo_object = ctx.attr.library.cgo_object

if not go_srcs:
fail("may not be empty", "srcs")

Expand All @@ -303,8 +304,8 @@ def go_library_impl(ctx):
extra_objects += [obj]

out_lib = ctx.outputs.lib
emit_go_compile_action(ctx, go_srcs, deps, out_lib,
extra_objects=extra_objects)
gc_goopts = _gc_goopts(ctx)
_emit_go_compile_action(ctx, go_srcs, deps, out_lib, extra_objects, gc_goopts)

transitive_libs = set([out_lib])
transitive_importmap = {out_lib.path: _go_importpath(ctx)}
Expand All @@ -329,7 +330,8 @@ def go_library_impl(ctx):
transitive_go_library_object = transitive_libs,
cgo_object = cgo_object,
transitive_cgo_deps = transitive_cgo_deps,
transitive_go_importmap = transitive_importmap
transitive_go_importmap = transitive_importmap,
gc_goopts = gc_goopts,
)

def _c_linker_options(ctx, blacklist=[]):
Expand Down Expand Up @@ -371,8 +373,22 @@ def _short_path(f):
fail("file name %s is not prefixed with its root %s", f.path, prefix)
return f.path[len(prefix):]

def emit_go_link_action(ctx, importmap, transitive_libs, cgo_deps, lib,
executable, x_defs={}):
def _gc_goopts(ctx):
gc_goopts = [ctx.expand_make_variables("gc_goopts", f, {})
for f in ctx.attr.gc_goopts]
if ctx.attr.library:
gc_goopts += ctx.attr.library.gc_goopts
return gc_goopts

def _gc_linkopts(ctx):
gc_linkopts = [ctx.expand_make_variables("gc_linkopts", f, {})
for f in ctx.attr.gc_linkopts]
for k, v in ctx.attr.x_defs.items():
gc_linkopts += ["-X", "%s='%s'" % (k, v)]
return gc_linkopts

def _emit_go_link_action(ctx, importmap, transitive_libs, cgo_deps, lib,
executable, gc_linkopts):
"""Sets up a symlink tree to libraries to link together."""
out_dir = executable.path + ".dir"
out_depth = out_dir.count('/') + 1
Expand Down Expand Up @@ -412,11 +428,7 @@ def emit_go_link_action(ctx, importmap, transitive_libs, cgo_deps, lib,
('../' * out_depth) + ctx.file.go_tool.path,
"tool", "link", "-L", ".",
"-o", _go_importpath(ctx),
'"${STAMP_XDEFS[@]}"',
]

if x_defs:
link_cmd += [" -X %s='%s' " % (k, v) for k,v in x_defs.items()]
] + gc_linkopts + ['"${STAMP_XDEFS[@]}"']

# workaround for a bug in ld(1) on Mac OS X.
# http://lists.apple.com/archives/Darwin-dev/2006/Sep/msg00084.html
Expand Down Expand Up @@ -476,13 +488,13 @@ def go_binary_impl(ctx):
executable = ctx.outputs.executable
lib_out = ctx.outputs.lib

emit_go_link_action(
_emit_go_link_action(
ctx,
transitive_libs=lib_result.transitive_go_library_object,
importmap=lib_result.transitive_go_importmap,
cgo_deps=lib_result.transitive_cgo_deps,
lib=lib_out, executable=executable,
x_defs=ctx.attr.x_defs)
gc_linkopts=_gc_linkopts(ctx))

runfiles = ctx.runfiles(collect_data = True,
files = ctx.files.data)
Expand Down Expand Up @@ -514,18 +526,23 @@ def go_test_impl(ctx):
arguments = args,
env = dict(go_environment_vars(ctx), RUNDIR=ctx.label.package))

emit_go_compile_action(
ctx, set([main_go]), ctx.attr.deps + [lib_result], ctx.outputs.main_lib)
_emit_go_compile_action(
ctx,
sources=set([main_go]),
deps=ctx.attr.deps + [lib_result],
out_lib=ctx.outputs.main_lib,
extra_objects=[],
gc_goopts=_gc_goopts(ctx))

importmap = lib_result.transitive_go_importmap + {
ctx.outputs.main_lib.path: _go_importpath(ctx) + "_main_test"}
emit_go_link_action(
_emit_go_link_action(
ctx,
importmap=importmap,
transitive_libs=lib_result.transitive_go_library_object,
cgo_deps=lib_result.transitive_cgo_deps,
lib=ctx.outputs.main_lib, executable=ctx.outputs.executable,
x_defs=ctx.attr.x_defs)
gc_linkopts=_gc_linkopts(ctx))

# TODO(bazel-team): the Go tests should do a chdir to the directory
# holding the data files, so open-source go tests continue to work
Expand Down Expand Up @@ -597,8 +614,10 @@ go_library_attrs = go_env_attrs + {
"go_sources",
"asm_sources",
"cgo_object",
"gc_goopts",
],
),
"gc_goopts": attr.string_list(),
}

_crosstool_attrs = {
Expand All @@ -607,6 +626,12 @@ _crosstool_attrs = {
),
}

go_link_attrs = go_library_attrs + _crosstool_attrs + {
"gc_linkopts": attr.string_list(),
"linkstamp": attr.string(),
"x_defs": attr.string_dict(),
}

go_library_outputs = {
"lib": "%{name}.a",
}
Expand All @@ -627,27 +652,22 @@ go_library = rule(

go_binary = rule(
go_binary_impl,
attrs = go_library_attrs + _crosstool_attrs + {
"linkstamp": attr.string(default = ""),
"x_defs": attr.string_dict(),
},
attrs = go_library_attrs + _crosstool_attrs + go_link_attrs,
executable = True,
fragments = ["cpp"],
outputs = go_library_outputs,
)

go_test = rule(
go_test_impl,
attrs = go_library_attrs + _crosstool_attrs + {
attrs = go_library_attrs + _crosstool_attrs + go_link_attrs + {
"test_generator": attr.label(
executable = True,
default = Label(
"//go/tools:generate_test_main",
),
cfg = "host",
),
"linkstamp": attr.string(default = ""),
"x_defs": attr.string_dict(),
},
executable = True,
fragments = ["cpp"],
Expand Down Expand Up @@ -883,6 +903,7 @@ def _cgo_genrule_impl(ctx):
asm_sources = [],
cgo_object = ctx.attr.cgo_object,
direct_deps = ctx.attr.deps,
gc_goopts = [],
)

_cgo_genrule = rule(
Expand Down
Loading