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

bazel targets for stdlib packages or alternative ideas? #1944

Closed
jmhodges opened this issue Feb 8, 2019 · 4 comments
Closed

bazel targets for stdlib packages or alternative ideas? #1944

jmhodges opened this issue Feb 8, 2019 · 4 comments

Comments

@jmhodges
Copy link
Contributor

jmhodges commented Feb 8, 2019

A user of bazel_gomock just opened an issue where they'd like to generate a mock for an interface in the stdlib.

Bazel_gomock accepts go_library targets as the library parameter to generate the GOPATHs we need to satisfy those libraries. That means it would need a go_library to the specific package in the stdlib. However, it looks like rules_go (through @go_sdk) doesn't supply those.

It would be nice if rules_go did provide bazel targets for the individual stdlib packages for tooling purposes.

But I'm also open to other design ideas if y'all have them.

(For instance, I've thought about adding magic code that reverse mapped from import paths to bazel targets to figure out what it needed instead of the library param, but I'm not sure if that works in the general case. I was hoping to keep folks in the bazel way of referring to things instead of having them flip between bazel and go style inside BUILD files, but I could be convinced not to. Does that exist as a tool already in rules_go?)

@jayconrod
Copy link
Contributor

It would probably be possible to define go_tool_library targets for the majority of packages in std, but there are a bunch of edge cases that cmd/go handles specifically. I'd rather not mess with that. Also keep in mind, in the future, users will be able to declare multiple SDK repositories, and the correct one will be selected dynamically based on the execution platform. So avoid referencing @go_sdk, since it may not be the SDK in use.

What exactly does gomock get from the library attribute? I'm guessing you need the import path and the source files? For the standard library, you can call all the source files through go.sdk.toolchain.srcs. But the import path would need to be explicitly specified. Maybe something like this?

gomock(
    name = "mock_addr",
    out = "mock_addr_test.go",
    interfaces = ["Addr"],
    std_library = "net",
    package = "main",
)

For instance, I've thought about adding magic code that reverse mapped from import paths to bazel targets to figure out what it needed instead of the library param, but I'm not sure if that works in the general case.

We used to have this with go_prefix, before importpath was introduced. It imposed some pretty strict requirements on repository structure that caused a lot of problems though. I'd encourage sticking to the Bazel style as much as possible

@jmhodges
Copy link
Contributor Author

jmhodges commented Feb 10, 2019

bazel_gomock uses the library to create the GOPATH of source files with go_path but also the mockgen tool (that bazel_gomock) uses the actual library to link against for creating the binary that generates the interfaces. So, we def want the actual .a library around and need to be able to reference it as a bazel dependency.

(mockgen creates that binary that in order to use Go reflect tooling to correctly import packages they need to satisfy types from other packages that are referenced as return or argument types)

@jmhodges
Copy link
Contributor Author

jmhodges commented Feb 10, 2019

Referencing the code: https://github.com/jmhodges/bazel_gomock/blob/ff6c20a9b6978c52b88b7a1e2e55b3b86e26685b/gomock.bzl#L110

(mockgen has the -prog_only and -exec_only flags called in two different binaries specifically for cases like bazel where we want to reuse the already compiled code our build system provides. Using those flags sped up bazel_gomock consideribly)

@jayconrod
Copy link
Contributor

Makes sense, thanks for explaining.

So if you're using go_rule and go_context, you'll have access to the standard library and the SDK.

For standard library sources, use go.sdk.srcs. You can use go.sdk.root_file to find the root directory here.

For standard library packages, use go.stdlib.libs. go.stdlib.root_file will be in the root directory.

These will usually both point to wherever the SDK was checked out, but in cross-compiling configurations, the packages will be compiled somewhere else. The sources will not be present at the other location.

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

2 participants