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/go: link-time symbol resolution for buildmode=c-shared #12216

Open
deweerdt opened this Issue Aug 20, 2015 · 9 comments

Comments

Projects
None yet
7 participants
@deweerdt

deweerdt commented Aug 20, 2015

version:

$ go version
go version go1.5 linux/amd64

I'm working with a software that loads plugins structured as follows. Plugins implement an interface, and the main program provides an API, so a typical call stack might look like:

main_program_function()
\_ plugin_function()
   \_ main_program_other_function()

Up to now, the main program and the plugins are written in C. I was eager to see if I could start building plugins in Go instead of C, now that 1.5 is out, so I gave it a try with something that looks like:

package main

// #include "main_program_api.h"
import "C"

//export plugin_function
func plugin_function() {
   C.main_program_other_function()
}

func main () {
 // unused
}

Unfortunately, this fails with:

./plugin.go:8: undefined reference to `main_program_other_function'

Ian Lance Taylor suggested I pass '--unresolved-symbols' to the linker as a work around. I verified that that works as expected, both when passed via the command line:

CGO_LDFLAGS="-Wl,--unresolved-symbols=ignore-all" go build -buildmode=c-shared 

or via the code

// #cgo LDFLAGS: -Wl,--unresolved-symbols=ignore-all

@ianlancetaylor ianlancetaylor changed the title from Link time symbol resolution for buildmode=c-shared to cmd/go: Link time symbol resolution for buildmode=c-shared Aug 20, 2015

@ianlancetaylor ianlancetaylor added this to the Go1.6 milestone Aug 20, 2015

@rsc

This comment has been minimized.

Contributor

rsc commented Nov 5, 2015

It sounds like Ian fixed your problem.

Are you proposing a change for the toolchain?

@rsc rsc changed the title from cmd/go: Link time symbol resolution for buildmode=c-shared to cmd/go: link-time symbol resolution for buildmode=c-shared Nov 5, 2015

@deweerdt

This comment has been minimized.

deweerdt commented Nov 5, 2015

@rsc I do think that passing '--unresolved-symbols=ignore-all' would be a better defaut, but I can't say I feel strongly about it.

@rsc rsc modified the milestones: Go1.6Maybe, Go1.6 Dec 17, 2015

@rsc

This comment has been minimized.

Contributor

rsc commented Jan 6, 2016

@ianlancetaylor, should we make -Wl,--unresolved-symbols=ignore-all the default for buildmode=c-shared uses of cgo?

If so, let's wait until Go 1.7 since the c-shared stuff is still experimental and there's an easy workaround. Otherwise, let's close the bug.

@rsc rsc modified the milestones: Go1.7, Go1.6Maybe Jan 6, 2016

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Jan 6, 2016

The issue here isn't really with -buildmode=c-shared. It's with using cgo to call a function that is not defined as far as cgo knows, because it is actually defined in a Go package. This comes up pretty naturally with -buildmode=c-shared, but it's easy to construct a similar case in other build modes as well.

The real fix might be to have cgo do its links with -r, and not fuss about undefined symbols. Or have cgo use --unresolved-symbols=ignore-all; I'm not sure which would work better. Either way, we would let the final link give any errors about undefined symbols.

@rsc rsc modified the milestones: Go1.8, Go1.7 May 17, 2016

@rsc

This comment has been minimized.

Contributor

rsc commented Oct 21, 2016

@ianlancetaylor, sorry for the delayed response, but can you explain the difference between -r and --unresolved-symbols=ignore-all? Which should we use?

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Oct 21, 2016

The two options are completely different. Using -r tells the linker to generate a relocatable object file. Using --unresolved-symbols=ignore-all tells the linker to not report errors about undefined symbols. The advantage of -r is that most linkers support it. The advantage of --unresolved-symbols=ignore-all is that it does a normal link, not a relocatable link, so we don't have to deal with relocations.

For either one I'm not quite sure what will happen with an undefined symbol. We may be left without any using DWARF info, which could be a problem in some cases.

@rsc rsc modified the milestones: Go1.9, Go1.8 Nov 11, 2016

@asottile

This comment has been minimized.

Contributor

asottile commented Jan 31, 2017

I just stumbled on this thread while searching for the same thing (I'm attempting to build python modules written in go). This solution was perfect, +1 for it becoming the default.

@sbinet

This comment has been minimized.

Member

sbinet commented Jan 31, 2017

@asottile it's only tangential but still a bit related: did you look at gopy to create python modules written in Go ?

@asottile

This comment has been minimized.

Contributor

asottile commented Jan 31, 2017

Yeah it's not suitable for what I want to do. You can see what I've done here though : https://github.com/asottile/setuptools-golang

@rsc rsc modified the milestones: Go1.10, Go1.9 Jun 12, 2017

ivilata added a commit to equalitie/ipfs-cache that referenced this issue Nov 9, 2017

@rsc rsc modified the milestones: Go1.10, Go1.11 Dec 1, 2017

@gopherbot gopherbot modified the milestones: Go1.11, Unplanned May 23, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment