Skip to content

cmd/go: can't link programs that depend on transitive binary only packages #23473

Closed
@ianlancetaylor

Description

@ianlancetaylor

At current tip (git revision 4b3a3bd) building a program that depends on a transitive link of binary only packages does not work, because importcfg.link does not represent all the dependencies.

Written in the form of a test in cmd/go/go_test.go:

func TestBinaryOnlyLink(t *testing.T) {
	tg := testgo(t)
	defer tg.cleanup()
	tg.parallel()
	tg.makeTempdir()
	tg.setenv("GOPATH", tg.path("."))

	// Build the packages to get the binaries,
	// then change them to be binary-only.
	tg.tempFile("src/p1/p1.go", `package p1; import "p2"; func F() { p2.G() }`)
	tg.tempFile("src/p2/p2.go", `package p2; func G() {}`)
	tg.run("install", "p1", "p2")
	tg.must(os.Remove(tg.path("src/p1/p1.go")))
	tg.must(os.Remove(tg.path("src/p2/p2.go")))
	tg.tempFile("src/p1/binary.go", `//go:binary-only-package

	package p1`)
	tg.tempFile("src/p2/binary.go", `//go:binary-only-package

	package p2`)

	tg.tempFile("src/main/main.go", `package main; import "p1"; func main() { p1.F() }`)
	tg.run("build", "-o", tg.path("main"), "main")
}

This fails with

--- FAIL: TestBinaryOnlyLink (0.07s)
	go_test.go:4059: running testgo [install p1 p2]
	go_test.go:4070: running testgo [build -o /tmp/gotest226647203/main main]
	go_test.go:4070: standard error:
	go_test.go:4070: # main
		cannot find package p2 (using -importcfg)
		/home/iant/go/pkg/tool/linux_amd64/link: cannot open file : open : no such file or directory
		
	go_test.go:4070: go [build -o /tmp/gotest226647203/main main] failed unexpectedly: exit status 2

The problem is that the importcfg.link file describes how to find p1.a, but not how to find p2.a. The internal Package struct built for p1 does not list p2 as a dep (since p1 is binary only) so (*Builder).addTransitiveLinkDeps does not add p2 as a Dep, so it is not added to importcfg.link.

CC @rsc

Activity

added this to the Go1.10 milestone on Jan 18, 2018
rsc

rsc commented on Jan 22, 2018

@rsc
Contributor

Unfortunate, but working as documented: https://tip.golang.org/doc/go1.10.

Many details of the go build implementation have changed to support these improvements. One new requirement implied by these changes is that binary-only packages must now declare accurate import blocks in their stub source code, so that those imports can be made available when linking a program using the binary-only package. For more details, see go help filetype.

And go help filetype:

Non-test Go source files can also include a //go:binary-only-package comment, indicating that the package sources are included for documentation only and must not be used to build the package binary. This enables distribution of Go packages in their compiled form alone. Even binary-only packages require accurate import blocks listing required dependencies, so that those dependencies can be supplied when linking the resulting command.

locked and limited conversation to collaborators on Jan 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @rsc@ianlancetaylor@gopherbot

        Issue actions

          cmd/go: can't link programs that depend on transitive binary only packages · Issue #23473 · golang/go