I've switched (or, am in the process of switching) to using bazel, though I'm doing so on Windows. I'm interested in calling into my Go code from Java, so I started with this tutorial.
I was able to make that work using the same code as on their Github example and everything works fine. I tried adapting that to my bazel build. If I take the awesome.so
file generated by go build -o awesome.so -buildmode=c-shared awesome.go
and include it as a resource to my java_library
, I can make everything work.
Relevant files shown below.
Ideally, however, I'd like to have everything generated through bazel, but despite all my attempts thus far my go_binary
rule always outputs awesome.a
(and awesome.x
). If I switch to using //go:awesome
as the resource from java:client_lib
I am able to successfully see the awesome.a
output as a resource, which suggests that getting my go_binary
to output awesome.so
is the last piece of the puzzle, but the correct combination of flags has thus far eluded me.
Basically I just want to make my go_binary
rule have the same behavior as running go build -o awesome.so --buildmode=c-shared awesome.go
.
In theory I'm ok if I need another rule to bridge the gap, but since I'm on windows and bash has been hit or miss thus far, using genrule
as the intermediate doesn't currently look promising.
Please advise, and thanks!
WORKSPACE
...
# bazelbuild/rules_go for golang support.
http_archive(
name = "io_bazel_rules_go",
sha256 = "b725e6497741d7fc2d55fcc29a276627d10e43fa5d0bb692692890ae30d98d00",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.24.3/rules_go-v0.24.3.tar.gz",
],
)
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
go_register_toolchains()
...
go/awesome.go is copied from the article.
go/BUILD
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
package(default_visibility = ["//visibility:public"])
go_binary(
name = "awesome",
srcs = glob(["*.go"]),
cgo = True,
copts = [
"-fPIC", # I tried adding this after some other reading about .a->.so
],
gc_linkopts = [
"-shared", # I think this is equivalent to the linkmode=c-shared below, but... <shrug>
],
linkmode = "c-shared",
static = "off",
)
# This one uses the pre-built awesome.so, and this works.
filegroup(
name = "prebuilt_awesome_resource",
srcs = ["awesome.so"],
)
java/Client.java is copied from the github repo linked in the article (with slight tweaks to the library's location).
java/BUILD
package(default_visibility = ["//visibility:public"])
java_import(
name = "jna",
jars = ["jna.jar"],
)
java_library(
name = "client_lib",
srcs = glob(["*.java"]),
resources = [
# "//go:awesome", # I'd rather use this one.
"//go:prebuilt_awesome_resource",
],
deps = [
":jna",
],
)
java_binary(
name = "client",
main_class = "Client",
runtime_deps = [
":client_lib",
],
)
and also, since it was important getting go stuff to run:
%programdata%/basel.bazelrc
startup --output_user_root="C:/_bazel_out"
build --compiler=mingw-gcc
Well, I guess I need to go sit in the shame cube for a while.
Of all the options I was looking at for the compiler I missed checking other attributes on go_binary
. Specifically, the obvious one, out
. The one that actually corresponds to the -o
flag on go build
I added out = "awesome.so"
to my go_binary
rule and, sure enough, everything works.
Well that's a few hours wasted. Thanks Jay for trying to help and sorry for asking a dumb question.