diff --git a/go/private/context.bzl b/go/private/context.bzl index b6d9d60a7f..cb283e1c33 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -134,6 +134,28 @@ def _merge_embed(source, embed): fail("multiple libraries with cgo_archives embedded") source["cgo_archives"] = s.cgo_archives +def _dedup_deps(deps): + """Returns a list of targets without duplicate import paths. + + Earlier targets take precedence over later targets. This is intended to + allow an embedding library to override the dependencies of its + embedded libraries. + """ + deduped_deps = [] + importpaths = {} + for dep in deps: + # TODO(#1784): we allow deps to be a list of GoArchive since go_test and + # nogo work this way. We should force deps to be a list of Targets. + if hasattr(dep, "data") and hasattr(dep.data, "importpath"): + importpath = dep.data.importpath + else: + importpath = dep[GoLibrary].importpath + if importpath in importpaths: + continue + importpaths[importpath] = None + deduped_deps.append(dep) + return deduped_deps + def _library_to_source(go, attr, library, coverage_instrumented): #TODO: stop collapsing a depset in this line... attr_srcs = [f for t in getattr(attr, "srcs", []) for f in as_iterable(t.files)] @@ -158,6 +180,7 @@ def _library_to_source(go, attr, library, coverage_instrumented): source["cover"] = attr_srcs for e in getattr(attr, "embed", []): _merge_embed(source, e) + source["deps"] = _dedup_deps(source["deps"]) x_defs = source["x_defs"] for k, v in getattr(attr, "x_defs", {}).items(): if "." not in k: diff --git a/tests/core/go_library/BUILD.bazel b/tests/core/go_library/BUILD.bazel index 4c057a5652..72a1d16cbd 100644 --- a/tests/core/go_library/BUILD.bazel +++ b/tests/core/go_library/BUILD.bazel @@ -29,3 +29,40 @@ go_library( ], importpath = "asm_header", ) + +go_library( + name = "package_height", + srcs = ["package_height.go"], + importpath = "package_height", + deps = [ + ":package_height_dep_deep", + ":package_height_embedder", + ], +) + +go_library( + name = "package_height_embedder", + srcs = ["package_height_embedder.go"], + embed = [":package_height_embeddee"], + importpath = "package_height/embed", + deps = [":package_height_dep_deep"], +) + +go_library( + name = "package_height_embeddee", + srcs = ["package_height_embeddee.go"], + importpath = "package_height/embed", + deps = [":package_height_dep_shallow"], +) + +go_library( + name = "package_height_dep_deep", + srcs = ["package_height_dep_deep.go"], + importpath = "package_height/dep", +) + +go_library( + name = "package_height_dep_shallow", + srcs = ["package_height_dep_shallow.go"], + importpath = "package_height/dep", +) diff --git a/tests/core/go_library/README.rst b/tests/core/go_library/README.rst index 7063f5edbf..4e90c4a99f 100644 --- a/tests/core/go_library/README.rst +++ b/tests/core/go_library/README.rst @@ -4,6 +4,7 @@ Basic go_library functionality .. _go_library: /go/core.rst#_go_library .. #1262: https://github.com/bazelbuild/rules_go/issues/1262 .. #1520: https://github.com/bazelbuild/rules_go/issues/1520 +.. #1772: https://github.com/bazelbuild/rules_go/issues/1772 empty ----- @@ -22,3 +23,9 @@ asm_header Checks that assembly files in a `go_library`_ may include ``"go_asm.h"``, generated by the compiler. Verifies `#1262`_. + +package_height +-------------- + +Checks that when a library embeds another library, the embedder's dependencies +may override the embeddee's dependencies. Verifies `#1772`_. diff --git a/tests/core/go_library/package_height.go b/tests/core/go_library/package_height.go new file mode 100644 index 0000000000..cafb5fafb1 --- /dev/null +++ b/tests/core/go_library/package_height.go @@ -0,0 +1,6 @@ +package height + +import "package_height/embed" +import "package_height/dep" + +var X = embed.T{F: dep.T{}} diff --git a/tests/core/go_library/package_height_dep_deep.go b/tests/core/go_library/package_height_dep_deep.go new file mode 100644 index 0000000000..139a805d2b --- /dev/null +++ b/tests/core/go_library/package_height_dep_deep.go @@ -0,0 +1,7 @@ +package dep + +import "os" + +type T struct { + F *os.File +} diff --git a/tests/core/go_library/package_height_dep_shallow.go b/tests/core/go_library/package_height_dep_shallow.go new file mode 100644 index 0000000000..1902c0350f --- /dev/null +++ b/tests/core/go_library/package_height_dep_shallow.go @@ -0,0 +1,3 @@ +package dep + +type T struct{} diff --git a/tests/core/go_library/package_height_embeddee.go b/tests/core/go_library/package_height_embeddee.go new file mode 100644 index 0000000000..0c36a32a29 --- /dev/null +++ b/tests/core/go_library/package_height_embeddee.go @@ -0,0 +1,7 @@ +package embed + +import "package_height/dep" + +type T struct { + F dep.T +} diff --git a/tests/core/go_library/package_height_embedder.go b/tests/core/go_library/package_height_embedder.go new file mode 100644 index 0000000000..81a00369dd --- /dev/null +++ b/tests/core/go_library/package_height_embedder.go @@ -0,0 +1,3 @@ +package embed + +var X = T{}