Go and Bazel:使用外部Git存储库

Thus far, I have been using go tool to fetch dependencies. I've set $GOPATH to ~/projects/holygrail, and I've checked out my code into src/mycodehosting.foo/myuser/holygrail.

Given that I actually depend on things such as gRPC, which means I need to build protoc from protobuf v3's source, I've written a small script that helps me do this. I would strongly prefer to not have to pre-prepare layout when I check out my source code, and I would strongly prefer not to use a bash script to fetch my dependencies, and then build them.

Current tentative solution:

  • use Git submodules to fetch external dependencies (which, sadly, means no smart redirects that go get knows how to do)
  • use Go 1.5's vendoring by flipping the GO15VENDOREXPERIMENT variable to 1
  • switch to Bazel to have a sane build system which will know how to build various dependencies only as required

Unfortunately, I am slightly stuck.

  • I'm using Bazel 0.1.1 with Skylark rules for Go from git repo copied into ~/.bazel/base_workspace
  • I originally tried using new_local_repository (later to be switched to use new_git_repository) inside Bazel's WORKSPACE, specifying a custom BUILD file for one of the dependencies
    • this broke down because Bazel was unable to find the Go Skylark rules
  • I am not sure how would I write custom BUILD-files for git-submodule-downloaded repositories in vendor/ folder, and expose them to Bazel.

Am I on the right track? Am I correct to use submodules? Am I correct to use vendor/ subfolder to store Go libraries?

  • What is the recommended way to build external dependencies using Bazel, where both the code and the dependencies are written in Go?
  • Could you provide an example of a repository that:
    • correctly depends on an external BUILD-file-less Go repository (without actually importing the upstream code)?
    • correctly builds the Go code in the external repository?
    • correctly integrates the Go code from the external repository into the main Go project?

Some more research into this:

  • Kythe seems to have one BUILD file for many dependencies (even though they are not submodules, that does not make a difference).
  • That helper rule uses the go_package() rule. But this seems to come from Kythe itself.
    • It doesn't seem right to start using rules from Kythe, but it seems like a possible way to go?
    • What do other people do?

As of few versions ago, Bazel supports slashes in rule names. Along with hacked-in support for custom package names (https://github.com/bazelbuild/rules_go/issues/16) this seems to cover my use case.

tl;dr I have //vendor:BUILD file which has rules such as go_library(name='github.com/blah/blah', ...). Directories are named, e.g., //vendor/github.com/blah/blah. Each subpackage has a separate rule. I've manually specified dependencies.