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

Linker fails with fingerprint mismatch in google.golang.org/genproto/ #2758

Open
yasushi-saito opened this issue Dec 14, 2020 · 5 comments
Open
Labels

Comments

@yasushi-saito
Copy link
Contributor

What version of rules_go are you using?

1.24.0

What version of gazelle are you using?

0.21.1

What version of Bazel are you using?

3.5.0

Does this issue reproduce with the latest releases of all the above?

yes

What operating system and processor architecture are you using?

Linux, Ubuntu 20.04, x64

Any other potentially useful information about your toolchain?

What did you do?

bazel build a go binary

What did you expect to see?

it should succeed.

What did you see instead?

external/go_sdk/pkg/tool/linux_amd64/link: fingerprint mismatch: google.golang.org/genproto/protobuf/field_mask has 55575cc1e0bac241, import from google.golang.org/genproto/googleapis/cloud/secretmanager/v1beta1 expecting a37ceb1aa706ceb1

Some of the pertinent lines in go.mod (and the matching bazel workspace rules are):

	google.golang.org/genproto v0.0.0-20201211151036-40ec1c210f7a
	google.golang.org/grpc v1.34.0
	google.golang.org/protobuf v1.25.0

Sorry for a vague error description; the binary in question is from a fairly large non-opensource project and I wasn't able to create a simple repro. This error disappears when I remove some deps from BUILD files, but I can't quite figure out the minimal set of deps to make the problem happen.

I find it strange that secretmanager/v1beta1 is using protobuf/field_mask in the same package and fails with a fingerprint mismatch. Can someone give me some guidance as to how to investigate this problem?

@yasushi-saito yasushi-saito changed the title external/go_sdk/pkg/tool/linux_amd64/link: fingerprint mismatch: google.golang.org/genproto/protobuf/field_mask has 55575cc1e0bac241, import from google.golang.org/genproto/googleapis/cloud/secretmanager/v1beta1 expecting a37ceb1aa706ceb1 Linker fails with fingerprint mismatch in google.golang.org/genproto/ Dec 14, 2020
@jayconrod
Copy link
Contributor

This error happens when multiple packages with the same importpath (or importmap, if set) are linked into the same binary. The Go 1.15 linker rejects this when a package is compiled against a package with different export data than it's linked with. Even if the linker doesn't complain, this is not safe.

This is especially common with protos, since it's easy to mix pre-generated go_library targets with go_proto_library targets that refer to the same packages. Avoiding conflicts has more information on resolving those.

There have been a number of bug fixes on the rules_go 0.24.x branch, so please try upgrading to that or 0.25.x. You'll likely see better error messages there.

@yasushi-saito
Copy link
Contributor Author

Thanks for the help. When I use rules_go 0.25, I now get a different error:

/home/saito/src4/go/core/status/status.go:19:2: internal compiler error: conflicting package heights 24 and 23 for path "google.golang.org/genproto/googleapis/rpc/status"

Grepping through the packages downloaded by Bazel, I see that rules in the following two packages both define a library whose import path is
google.golang.org/genproto/googleapis/rpc/status

./go_googleapis/google/rpc/BUILD.bazel
./com_google_googleapis/google/rpc/BUILD.bazel

It looks like they are both imported by rules_go. Is there a way around it?

The content of the former file is:

load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")

proto_library(
    name = "code_proto",
    srcs = ["code.proto"],
    visibility = ["//visibility:public"],
)

proto_library(
    name = "errdetails_proto",
    srcs = ["error_details.proto"],
    visibility = ["//visibility:public"],
    deps = ["@com_google_protobuf//:duration_proto"],
)

proto_library(
    name = "status_proto",
    srcs = ["status.proto"],
    visibility = ["//visibility:public"],
    deps = ["@com_google_protobuf//:any_proto"],
)

go_proto_library(
    name = "code_go_proto",
    importpath = "google.golang.org/genproto/googleapis/rpc/code",
    proto = ":code_proto",
    visibility = ["//visibility:public"],
)

go_proto_library(
    name = "errdetails_go_proto",
    importpath = "google.golang.org/genproto/googleapis/rpc/errdetails",
    proto = ":errdetails_proto",
    visibility = ["//visibility:public"],
)

go_proto_library(
    name = "status_go_proto",
    importpath = "google.golang.org/genproto/googleapis/rpc/status",
    proto = ":status_proto",
    visibility = ["//visibility:public"],
)

The latter is

load("@rules_proto//proto:defs.bzl", "proto_library")

# This is an API workspace, having public visibility by default makes perfect sense.
package(default_visibility = ["//visibility:public"])

##############################################################################
# Common
##############################################################################
proto_library(
    name = "code_proto",
    srcs = ["code.proto"],
    deps = [],
)

proto_library(
    name = "error_details_proto",
    srcs = ["error_details.proto"],
    deps = [
        "@com_google_protobuf//:duration_proto",
    ],
)

proto_library(
    name = "status_proto",
    srcs = ["status.proto"],
    deps = [
        "@com_google_protobuf//:any_proto",
    ],
)

##############################################################################
# Java
##############################################################################
load("@com_google_googleapis_imports//:imports.bzl", "java_proto_library")

java_proto_library(
    name = "rpc_java_proto",
    deps = [
        ":code_proto",
        ":error_details_proto",
        ":status_proto",
    ],
)

##############################################################################
# Go
##############################################################################
load("@com_google_googleapis_imports//:imports.bzl", "go_proto_library")

go_proto_library(
    name = "code_go_proto",
    importpath = "google.golang.org/genproto/googleapis/rpc/code",
    protos = [":code_proto"],
)

go_proto_library(
    name = "errdetails_go_proto",
    importpath = "google.golang.org/genproto/googleapis/rpc/errdetails",
    protos = [":error_details_proto"],
)

go_proto_library(
    name = "status_go_proto",
    importpath = "google.golang.org/genproto/googleapis/rpc/status",
    protos = [":status_proto"],
)

##############################################################################
# C++
##############################################################################
load(
    "@com_google_googleapis_imports//:imports.bzl",
    "cc_proto_library",
)

cc_proto_library(
    name = "code_cc_proto",
    deps = [":code_proto"],
)

cc_proto_library(
    name = "error_details_cc_proto",
    deps = [":error_details_proto"],
)

cc_proto_library(
    name = "status_cc_proto",
    deps = [":status_proto"],
)

##############################################################################
# Python
##############################################################################
load("@com_google_googleapis_imports//:imports.bzl", "py_proto_library")

py_proto_library(
    name = "code_py_proto",
    deps = [":code_proto"],
)

py_proto_library(
    name = "error_details_py_proto",
    deps = [":error_details_proto"],
)

py_proto_library(
    name = "status_py_proto",
    deps = [":status_proto"],
)

@jayconrod
Copy link
Contributor

go_googleapis and com_google_googleapis are based on the same repository, but they appear to Bazel as separate workspaces. #1986 is an open issue for unifying them.

Not sure I have a good solution at the moment. You could override one of them and provide build files that replace conflicting go_proto_library target with alias targets referring to the other repo. That's a lot of work though.

@lennycampino
Copy link

Any solution to this problem?

@yasushi-saito
Copy link
Contributor Author

In our case, (1) setting disable_global option in gazelle, (2) updating io_bazel_rules_go to 0.25.0, and (3) updating bazel_gazelle to 0.22.2 magically fixed the problem. I still don't know why.

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

No branches or pull requests

3 participants