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: Go referencing C + C referencing Go = duplicate symbols #11263

Closed
shazow opened this issue Jun 17, 2015 · 4 comments
Closed

cmd/link: Go referencing C + C referencing Go = duplicate symbols #11263

shazow opened this issue Jun 17, 2015 · 4 comments

Comments

@shazow
Copy link
Contributor

shazow commented Jun 17, 2015

In a recent master, combining the two examples here will yield a duplicate symbol error on build. Either example alone works fine.

$ go version
go version devel +a2aaede Wed Jun 17 14:55:39 2015 +0000 darwin/amd64
package main

// typedef int (*intFunc) ();
//
// int
// bridge_int_func(intFunc f)
// {
//      return f();
// }
//
// int fortytwo()
// {
//      return 42;
// }
import "C"
import "fmt"

//export Hello
func Hello() {}

func main() {
    f := C.intFunc(C.fortytwo)
    fmt.Println(int(C.bridge_int_func(f)))
    // Output: 42
}

Including the //export Hello line yields this error:

$ go build -buildmode=c-archive
# _/Users/shazow/projects/gohttplib
duplicate symbol _bridge_int_func in:
    $WORK/_/Users/shazow/projects/gohttplib/_obj/_cgo_export.o
    $WORK/_/Users/shazow/projects/gohttplib/_obj/gohttplib.cgo2.o
duplicate symbol _fortytwo in:
    $WORK/_/Users/shazow/projects/gohttplib/_obj/_cgo_export.o
    $WORK/_/Users/shazow/projects/gohttplib/_obj/gohttplib.cgo2.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Doesn't matter if the -buildmode=c-archive flag is included. If the //export Hello line is removed, it works fine. If the inline C code is removed, it works fine.

Scenario: I'm trying to pass a callback (function pointer) from C into a Go function and I was trying to use an inline bridge function for calling it.

@ianlancetaylor
Copy link
Contributor

This is documented at http://golang.org/cmd/cgo: "Using //export in a file places a restriction on the preamble: since it is copied into two different C output files, it must not contain any definitions, only declarations. Definitions must be placed in preambles in other files, or in C source files."

@shazow
Copy link
Contributor Author

shazow commented Jun 18, 2015

Aaah that's what that means, thank you. Let me know if you'd like a docs patch to mention the duplicate symbols consequence for clarity.

@ianlancetaylor
Copy link
Contributor

I'm happy to look at a doc patch if you think you can make it more clear. Thanks.

@shazow
Copy link
Contributor Author

shazow commented Jun 18, 2015

@ianlancetaylor Proposed an edit here: https://go-review.googlesource.com/#/c/11247/

ianlancetaylor pushed a commit that referenced this issue Jun 19, 2015
Spell out what will happen if a declaration and definition is included
in the same file, should help people who run into duplicate symbol
errors and search for relevant keywords.

This edit is based on opening issue #11263 erroneously.

Change-Id: I0645a9433b8668d2ede9b9a3f6550d802c26388b
Reviewed-on: https://go-review.googlesource.com/11247
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants