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

cmd/link: error with -buildmode=shared: "cannot implicitly include runtime/cgo in a shared library" #17177

Closed
ghost opened this issue Sep 21, 2016 · 8 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@ghost
Copy link

ghost commented Sep 21, 2016

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

1.7.1

What operating system and processor architecture are you using (go env)?

[olegs@localhost tests]$ GOROOT=/home/olegs/.go/go GOPATH=/home/olegs/projects/tests ~/.go/go/bin/go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/olegs/projects/tests"
GORACE=""
GOROOT="/home/olegs/.go/go"
GOTOOLDIR="/home/olegs/.go/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build144208683=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

What did you do?

It's too long, I attached the log to this ticket.
In a nutshell, made a hello-world example with shared libraries. It compiles with Go 1.6.1, but not with Go 1.7.1

What did you expect to see?

I expected app to compile

What did you see instead?

/home/olegs/.go/go/pkg/tool/linux_amd64/link: cannot implicitly include runtime/cgo in a shared library
build-log.txt

@ianlancetaylor ianlancetaylor changed the title cannot implicitly include runtime/cgo in a shared library cmd/link: error with -buildmode=shared: "cannot implicitly include runtime/cgo in a shared library" Sep 21, 2016
@ianlancetaylor ianlancetaylor added this to the Go1.8 milestone Sep 21, 2016
@ianlancetaylor
Copy link
Contributor

CC @mwhudson

@mwhudson
Copy link
Contributor

Does it work if you don't pass -a on the offending 'go build' invocation?

I admit that I run into this error sometimes and don't really understand why, and given that I implemented this it's probably a sign that something needs to be fixed...

@ghost
Copy link
Author

ghost commented Sep 22, 2016

But having -a would mean using some results from old build / possibly going through some caching, where this check isn't performed, wouldn't it? And yes, third time the charm: it did compile after two unsuccessful compilations without -a.

I tried to follow the linker's code around this error message, and I'm confused: I never wanted CGO, and in this particular place iscgo is false, yet for some reason it is followed by loadinternal("runtime/cgo").

Since I'm interested in any sort of solution to this: is there any way to completely avoid having to deal with CGO, or are some bits of it mandatory? If it is possible, then what do I need to do to exclude it?

@mwhudson
Copy link
Contributor

On 22 September 2016 at 23:16, least-olegs notifications@github.com wrote:

But having -a would mean using some results from old build / possibly
going through some caching, where this check isn't performed, wouldn't it?
And yes, third time the charm: it did compile after two unsuccessful
compilations without -a.

I tried to follow the linker's code around this error message, and I'm
confused: I never wanted CGO, and in this particular place iscgo is
false, yet for some reason it is followed by loadinternal("runtime/cgo").

Since I'm interested in any sort of solution to this: is there any way to
completely avoid having to deal with CGO, or are some bits of it mandatory?
If it is possible, then what do I need to do to exclude it?

cgo is unavoidable with -buildmode=shared. I suspect the real fix for this
issue is in cmd/go, not cmd/link.

@mwhudson
Copy link
Contributor

Ah so what's going on is that when the linker looks for the runtime package, it finds $WORK/runtime.a but there is no $WORK/runtime.shlibname file to indicate that it is part of a shared library as the shlibname files are only created as part of installation. When the shared library is linked as a separate step, the runtime.a is next to a runtime.shlibname, so the link loads libstd.so, including the runtime/cgo package and so the later search for runtime/cgo finds that it has already been loaded.

I guess a fix would be to have the shlibname files created after the library is built and just copy them for the install step. @ianlancetaylor does that make sense to you?

@ianlancetaylor
Copy link
Contributor

That seems to make sense, yes.

@mwhudson
Copy link
Contributor

I tried this for a while and got horribly confused. Will try again in a bit.

The same issue results in a more insidious bug though: if you go build -o exe $path where exe links against a stale shared library, the stale shared library is re-build and re-installed, but the generated exe does not link against it!

Relatedly although the shared library will be re-built and re-installed, the .a files that make up the shared library are not re-installed. The naive fix for that results in loops in the action graph though :/

@quentinmit quentinmit added the NeedsFix The path to resolution is known, but the work has not been done. label Oct 7, 2016
@rsc rsc modified the milestones: Go1.9, Go1.8 Nov 3, 2016
@bradfitz
Copy link
Contributor

bradfitz commented Jun 7, 2017

This looks like a cmd/go caching bug, which will be addressed in Go 1.10 with @rsc's cmd/go work, so closing this. Other bugs track cmd/go caching.

@bradfitz bradfitz closed this as completed Jun 7, 2017
@golang golang locked and limited conversation to collaborators Jun 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

6 participants