Search code examples
bazel

What are the options to fix/work-around a bazel package conflict?


I'm seeing the following error:

link: package conflict error: google.golang.org/genproto/googleapis/api/annotations: multiple copies of package passed to linker:
    @go_googleapis//google/api:annotations_go_proto
    @org_golang_google_genproto//googleapis/api/annotations:annotations
Set "importmap" to different paths or use 'bazel cquery' to ensure only one
package with this path is linked.

@org_golang_google_genproto//googleapis/api/annotations:annotations is being brought in through:

@com_github_uber_cadence//service/history:go_default_library
@com_github_uber_cadence//service/history:history
@com_github_uber_cadence//common/resource:resource
@com_github_uber_cadence//common/archiver/provider:provider
@com_github_uber_cadence//common/archiver/gcloud:gcloud
@com_github_uber_cadence//common/archiver/gcloud/connector:connector
@com_google_cloud_go_storage//:storage
@org_golang_google_genproto//googleapis/iam/v1:iam
@org_golang_google_genproto//googleapis/api/annotations:annotations

Can @org_golang_google_genproto//googleapis/api/annotations:annotations be disabled or shadowed by @go_googleapis//google/api:annotations_go_proto? If so, how?


Solution

  • Option I went with:

    Change what uses @org_golang_google_genproto//googleapis/api/annotations to use @go_googleapis//google/api:annotations_go_proto instead by using appropriate gazelle:resolve directives in the repositories.bzl file:

        go_repository(
            name = "com_google_cloud_go",
            build_directives = [
                # @go_googleapis is the modern version of @org_golang_google_genproto
                # use @go_googleapis to avoid dependency conflicts between the two
                "gazelle:resolve go google.golang.org/genproto/googleapis/iam/v1 @go_googleapis//google/iam/v1:iam_go_proto",  # keep
            ],
            …
        )
    
        go_repository(
            name = "com_google_cloud_go_storage",
            build_directives = [
                # @go_googleapis is the modern version of @org_golang_google_genproto
                # use @go_googleapis to avoid dependency conflicts between the two
                "gazelle:resolve go google.golang.org/genproto/googleapis/iam/v1 @go_googleapis//google/iam/v1:iam_go_proto",  # keep
                "gazelle:resolve go google.golang.org/genproto/googleapis/type/expr @go_googleapis//google/type:expr_go_proto",  # keep
                "gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @go_googleapis//google/api:annotations_go_proto",  # keep
            ],
            …
        )
    

    The following also works but I preferred the above since it uses the newer library:

    Change what uses @go_googleapis//google/api:annotations_go_proto to use @org_golang_google_genproto//googleapis/api/annotations instead by using appropriate gazelle:resolve directives in the root BUILD file:

    # gazelle:resolve go google.golang.org/genproto/googleapis/api/annotations @org_golang_google_genproto//googleapis/api/annotations
    

    Other options considered and reasons I didn't go with them:

    1. Upgrade to the latest @com_google_cloud_go_storage. Didn't go with this option because the latest version (v1.24.0 at the time of this post) still uses @org_golang_google_genproto.
    2. Upgrade @com_google_cloud_go_storage to use @go_googleapis. Didn't go with this option because it looked too difficult to get merged.
    3. repo_mapping = {"@org_golang_google_genproto" : "@go_googleapis"} for com_google_cloud_go_storage. Didn't go with this option because @go_googleapis isn't a drop-in replacement for @org_golang_google_genproto (@go_googleapis uses the prefix google while @org_golang_google_genproto uses the prefix googleapis).
    4. "gazelle:exclude **/common/archiver/gcloud/**" for com_github_uber_cadence. Didn't go with this option because common/archiver/provider depends on common/archiver/gcloud.
    5. Set prefix for go_googleapis from google to googleapis. Didn't go with this option because it breaks expectations for those familiar with go_googleapis standard practice.