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 -buildmode=plugin linkopt #539

Closed
mikedanese opened this issue Jun 14, 2017 · 8 comments
Closed

support -buildmode=plugin linkopt #539

mikedanese opened this issue Jun 14, 2017 · 8 comments
Assignees

Comments

@mikedanese
Copy link
Contributor

I tried

 11 go_binary(
 12     name = "gcp",
 13     gc_linkopts = ["-buildmode=plugin"],
 14     library = ":go_default_library",
 15     visibility = ["//visibility:public"],
 16 )

And got:

$ bazel build //plugin/...
INFO: Found 4 targets...
ERROR: /usr/local/google/home/mikedanese/go/src/containers.google.com/idmgr/plugin/gcp/BUILD:11:1: error executing shell command: 'bazel-out/local-fastbuild/bin/plugin/gcp/gcp.a.GoLinkFile.params' failed: Process exited with status 1 [sandboxed].
.init: reloc 15 to non-elf symbol .initdone· (outer=.initdone·) 32
.init: reloc 15 to non-elf symbol .initdone· (outer=.initdone·) 32
Use --strategy=GoLink=standalone to disable sandboxing for the failing actions.
INFO: Elapsed time: 0.378s, Critical Path: 0.12s
@jayconrod
Copy link
Contributor

I'd like to do this eventually, but it won't be simple. When you build a plugin, -buildmode=plugin goes to go build. The compiler, assembler, and linker don't get this flag directly; they get extra flags from go build instead. Dependencies also need to be compiled with those flags. Not sure how this interacts with cgo.

I tried building a small binary with -x, and it looks like it actually needs to recompile the standard library. Support for this might end up being similar to support race, asan, or tsan.

@ianthehat
Copy link
Contributor

I have a plan to allow support for this kind of thing using output groups but it's stacked up behind platforms and cross compilation and I'm not 100% sure it will work without actually trying it.

@ianthehat ianthehat self-assigned this Jun 19, 2017
@f0rmiga
Copy link
Member

f0rmiga commented Jan 2, 2018

@ianthehat Any progress on that? I'm very interested in this feature. :)

@ianthehat
Copy link
Contributor

No direct progress, but we are now in a good state to add more build modes. We build everything in multiple modes, including the standard library, so it's easy to add more, I have not done most of the -buildmode options only because I have no idea how they work or how people want to use them.
In the case of -buildmode=plugin for instance, should that option be on a go_binary rule? what should the output file name/type be on windows? How should another binary/library/test depend on a plugin? what should be put in runfiles?

@f0rmiga
Copy link
Member

f0rmiga commented Jan 3, 2018

Awesome!

For -buildmode=plugin I would find that a bit confusing on the go_binary rule because the output is in the form of a runtime loadable module (despite the package should be main and contain at least an empty func main()). I would expect that to be on the go_library rule. Up to now, -buildmode=plugin is allowed only on Linux, so the output, for now, would be only .so. On Windows, I think it makes sense to be .dll, but I'm not sure... I'm not a Windows user. On OS X I would expect it to be .so or .bundle (as recommended by Apple). In the end, I think it makes sense adding an option for setting the output file name.

Right now I'm loading the plugin in runtime using an environment variable that contains the path of the loadable module. So it is pretty flexible. I have no opinion on how to make it available to the binary/test, as long it is available to be easily loaded at runtime. Just so you can have a taste of how the plugin is loaded in Go:

filepath := "my_plugin.so" // Could be a relative path to the current working directory or an absolute path.
plug, err := plugin.Open(filepath)
if err != nil {
  ...
}

// Use plug...

I don't see a reason to make it available to another library since it is a runtime thing.

@ianthehat
Copy link
Contributor

So it's just like a binary, except you set buildmode=plugin when building it?
Do you know if it affects "go tool compile" or is it just "go tool link"
go_library is about building .a files, go_binary is about linking those files together. We could either have an option on go_binary, or a separate rule (go_plugin maybe)
If code that uses plugins does not need the plugin when compiling, only when running, then it can just go in the data/runfiles, so nothing special there. Do binaries that use plugins need anything special done to them as well?
Do you know of any very short examples of plugins I could look at to base a test off (I'm not going to write it if I can't test it :) )

@f0rmiga
Copy link
Member

f0rmiga commented Jan 4, 2018

I'm not sure how it is done internally. I never dig into it. I would assume it is just go tool link. I can do a research and get back to you tomorrow about that.

go_plugin would be perfect I think!

Binaries that load a plugin does not need anything special. With the go tooling, I just run the classic go build <path>.

There is this Medium post that I find very good. There is a very simple example in the post that you can base your tests!

ianthehat added a commit to ianthehat/rules_go that referenced this issue Jan 31, 2018
This removes the hard coded list of standard libraries, and builds it per aspect
being propagated.
This is both cleaner and a pre-requisite for the additional link modes to work.

Related to bazel-contrib#1264 and bazel-contrib#54 and bazel-contrib#539
ianthehat added a commit that referenced this issue Feb 2, 2018
* Build stdlib from inside the aspect

This removes the hard coded list of standard libraries, and builds it per aspect
being propagated.
This is both cleaner and a pre-requisite for the additional link modes to work.

Related to #1264 and #54 and #539

* review feedback
@jayconrod
Copy link
Contributor

This should work now with linkmode = "plugin" on go_binary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants