-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/cgo: undefined reference for C function with -buildmode=c-archive #25832
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
Comments
The cgo tool works this way because it needs to know the type of the C function You are doing something rather complicated: you are building a C archive, which is Go code callable from C. And you want that code, written in Go, to itself call a C function. So you have C calling Go calling C. I agree that in principle this ought to work. But in practice it's kind of complicated. Which is to say: yes, let's fix this if we can. But no promises on when or if anybody will look into it. |
Ok, I understand – I thought, it already parsed the comment abowe the |
Alternative possibility to allow declaring only C function would be something like this:
Like |
You might be able to do that today using |
I had no success with go:linkname to get the C function imported. |
Hi everyone, |
Until there is a better option, you can get it working by compiling the C code with -c and use that to compile the Go code and than link together those. For that, you have to have the declarations of the functions exported from the Go source. I did that by hand. I was even lazy enough to simply use int on both sides, which works on most architectures. I would suggest to create a feature request to be able to use this:
|
Hi @Andari85 , |
So, is there a specific way to create a feature request, or will this be picked up by someone? |
@Andari85 This issue is still open, so it is in effect a feature request. However, as I said above, it's kind of complicated, let's fix it if we can, but no promises on when or if anybody will look into it. Go is an open source project, so: volunteers welcome. I've already marked the issue as "help wanted". |
Okay, thanks. Well, I'm not much of a compiler guru, one day I might try to learn into the Go compiler. |
For what it's worth, I don't think that any fix to this will involve the compiler itself at all. I think all the work will be in the go tool and/or the cgo tool. |
I was able to achieve the requested result (a Go static library which can be invoked by a C main program and can, in turn, call exposed C functions in the main program) by doing the following: In the Go code, export functions as normal with the
Import cgo, and in the import declarations, declare the external C functions you want to call from Go.
Then, the important part: the cgo code needs to be compiled with the linker flag
These linker flags allow the Go code to successfully compile without having the external C functions defined anywhere, as they get looked up later when the C program they're in gets linked with the Go library. Then, finally, build the Go static library with So far this seems to work correctly for me, but I'd like to know from Go experts if there is anything wrong with this solution. Will certain features of Go, like goroutines/scheduling or memory management, not work correctly? They appear to be working, but I don't know enough about the technical details of Go to be sure... |
@zelbrium I don't think there is anything wrong with your solution. There are some oddball cases where it might fail if you want to use internal linking ( |
Hi everybody, |
@NickNaso I don't know for sure -- I'm not very experienced with MSVC -- but perhaps try the Alternatively, you might be able to use MinGW + GCC on Windows to compile with GCC instead of MSVC. Then the LDFLAGS should be the same as on Linux. Good luck! |
omg, finally i foud // export is wrong //export just don't add space after "//" |
@swq123459 From Go's Hidden Pragmas: "[No space after |
Is there any solution for Windows? Apparently |
@hajimehoshi I had your same problem and I created a fake dll library to link using
|
@NickNaso Thank you! I took a little different approach (creating a dummy DLL from a C file and linking it), and it worked well. |
Before this commit, if a go_library referenced an unresolved C symbol, the build would fail with an error about an undefined symbol since compilepkg.go tries to link all object files into an executable to be consumed by cgo's -dynimport argument. Since this library is never used for any purpose other than having its symbols parsed by the cgo command, retry with additional linker flags intended to make the linker ignore unresolved symbols. If they remain missing in the real link step, they will still be reported as unresolved there. Fixes golang/go#25832 for rules_go.
Before this commit, if a go_library referenced an unresolved C symbol, the build would fail with an error about an undefined symbol since compilepkg.go tries to link all object files into an executable to be consumed by cgo's -dynimport argument. Since this library is never used for any purpose other than having its symbols parsed by the cgo command, retry with additional linker flags intended to make the linker ignore unresolved symbols. If they remain missing in the real link step, they will still be reported as unresolved there. Fixes golang/go#25832 for rules_go.
Before this commit, if a go_library referenced an unresolved C symbol, the build would fail with an error about an undefined symbol since compilepkg.go tries to link all object files into an executable to be consumed by cgo's -dynimport argument. Since this library is never used for any purpose other than having its symbols parsed by the cgo command, retry with additional linker flags intended to make the linker ignore unresolved symbols. If they remain missing in the real link step, they will still be reported as unresolved there. Fixes golang/go#25832 for rules_go.
Before this commit, if a go_library referenced an unresolved C symbol, the build would fail with an error about an undefined symbol since compilepkg.go tries to link all object files into an executable to be consumed by cgo's -dynimport argument. Since this library is never used for any purpose other than having its symbols parsed by the cgo command, retry with additional linker flags intended to make the linker ignore unresolved symbols. If they remain missing in the real link step, they will still be reported as unresolved there. Fixes golang/go#25832 for rules_go.
…3174) Before this commit, if a go_library referenced an unresolved C symbol, the build would fail with an error about an undefined symbol since compilepkg.go tries to link all object files into an executable to be consumed by cgo's -dynimport argument. Since this library is never used for any purpose other than having its symbols parsed by the cgo command, retry with additional linker flags intended to make the linker ignore unresolved symbols. If they remain missing in the real link step, they will still be reported as unresolved there. Fixes golang/go#25832 for rules_go.
What version of Go are you using (
go version
)?go version go1.10.3 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/Andari/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/Andari/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.10.3/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.10.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/lw/5pzww_8n38g1lv_kqqmqfvqr0000gn/T/go-build228325343=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
I was experimenting with C interfacing:
I built it with
go build -buildmode=c-archive GoAdd.go
What did you expect to see?
The build to be successful.
What did you see instead?
Undefined symbols for architecture x86_64:
"_cadd", referenced from:
__cgo_ece3f0761be9_Cfunc_cadd in _x002.o
Why would linking be neccessary, if I am generating an archive which I link together with the cadd implementing object file later?
The text was updated successfully, but these errors were encountered: