Skip to content

zaccari/go_link

Repository files navigation

go_link

Bazel module for linking Go generated sources (protobuf files) into your source directory. This tool solves IDE integration issues when using Bazel-generated Go protobuf files.

Note: This is a maintained fork updated for Bazel 8.4.2+ with bzlmod support. The original project was created by Nikunj Yadav.

Find more details on this post written here

Purpose: Copy golang generated proto files into your source directory so your IDE can find them and your project remains go build compliant.

Note: This is a workaround until better native solutions exist for Bazel/Go/Proto IDE integration.

Requirements

  • Bazel 8.4.2+ (recommended to use Bazelisk)
  • Bzlmod enabled (default in Bazel 7+)
  • Gazelle for auto-generating build rules

Installation

For Bazel 8.4.2+ with Bzlmod (Recommended)

Add this to your MODULE.bazel file:

bazel_dep(name = "go_link", version = "2.0.0")

# If using from a git repository instead:
git_override(
    module_name = "go_link",
    remote = "https://github.com/zaccari/go_link.git",
    commit = "<commit-hash>",  # Use the latest commit
)

Legacy WORKSPACE Installation (Bazel < 7)

For older Bazel versions using WORKSPACE:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "go_link",
    urls = ["https://github.com/zaccari/go_link/archive/v2.0.0.tar.gz"],
    sha256 = "<sha256>",  # Update with actual SHA256
    strip_prefix = "go_link-2.0.0",
)

Setup

1. Configure Gazelle Binary

In your root BUILD or BUILD.bazel file:

load("@gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle", "gazelle_binary")

# Create a custom gazelle binary that includes the go_link plugin
gazelle_binary(
    name = "gazelle_binary",
    languages = DEFAULT_LANGUAGES + ["@go_link//gazelle/go_link"],
    visibility = ["//visibility:public"],
)

# Configure your gazelle target to use the custom binary
# gazelle:prefix github.com/example/your-project
gazelle(
    name = "gazelle",
    gazelle = ":gazelle_binary",
)

2. Run Gazelle

Generate BUILD.bazel files and go_proto_link targets:

bazelisk run //:gazelle

This will:

  • Generate BUILD.bazel files for your Go and proto code
  • Automatically create go_proto_link targets for each go_proto_library
  • Name them as <proto_name>_link

3. Copy Generated Proto Files

After running Gazelle, you'll have go_proto_link targets. Run them to copy generated .pb.go files:

# Copy all proto files in a specific package
bazelisk run //path/to/package:my_proto_link

# Or copy all proto files in your project
bazelisk run //...

This copies the generated .pb.go files from Bazel's build directory into your source tree.

Example Usage

Given a proto file at api/v1/user.proto:

  1. Run Gazelle:

    bazelisk run //:gazelle
  2. Gazelle generates in api/v1/BUILD.bazel:

    proto_library(
        name = "user_proto",
        srcs = ["user.proto"],
    )
    
    go_proto_library(
        name = "user_go_proto",
        proto = ":user_proto",
    )
    
    # Auto-generated by go_link gazelle plugin
    go_proto_link(
        name = "user_go_proto_link",
        dep = ":user_go_proto",
    )
  3. Copy generated files:

    bazelisk run //api/v1:user_go_proto_link
  4. Result: api/v1/user.pb.go is now in your source tree and your IDE can see it!

Manual Usage (Without Gazelle)

You can also manually use the go_proto_link rule:

load("@go_link//proto:proto.bzl", "go_proto_link")

go_proto_link(
    name = "my_proto_link",
    dep = ":my_go_proto_library",
    dir = "path/to/output/directory",  # Optional, defaults to package directory
)

How It Works

  1. Bazel generates .pb.go files in bazel-bin/ during go_proto_library builds
  2. go_proto_link extracts these files from the go_generated_srcs output group
  3. Creates an executable script that copies files to your source directory
  4. Running the target executes the copy operation
  5. Your IDE and go build can now see the generated files

Troubleshooting

Q: My IDE still can't find the proto files

  • Make sure you've run the go_proto_link target: bazelisk run //package:target_link
  • Check that .pb.go files exist in your source directory
  • Restart your IDE/language server

Q: Gazelle isn't generating go_proto_link targets

  • Verify you're using the custom gazelle_binary with the go_link plugin
  • Check that you have go_proto_library targets in your BUILD files
  • Re-run gazelle: bazelisk run //:gazelle

Q: Build fails with "OutputGroupInfo not found"

  • Ensure your go_proto_library rules are up to date
  • Check that you're using compatible versions of rules_go and protobuf

Migration from v1.x to v2.0

  1. Add MODULE.bazel to your project (if not already using bzlmod)
  2. Update the target reference from @go_link//gazelle/go_link:go_default_library to @go_link//gazelle/go_link
  3. Update any custom uses of go_link rules to use new repository names (@rules_go instead of @io_bazel_rules_go)
  4. Remove old WORKSPACE dependencies if fully migrated to bzlmod

Development

Common commands are available via the Makefile:

make help          # Show all available commands
make build         # Build all targets
make test          # Run all tests
make gazelle       # Generate/update BUILD files
make update-repos  # Update go dependencies
make format        # Format bazel files
make clean         # Clean bazel artifacts

Examples

See the original example commits for a complete setup:

License

See LICENSE file.

About

bazel hack for linking go generated srcs

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors