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/cgo: inline functions produce link errors #17356

Closed
wendigo opened this issue Oct 6, 2016 · 6 comments
Closed

cmd/cgo: inline functions produce link errors #17356

wendigo opened this issue Oct 6, 2016 · 6 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@wendigo
Copy link

wendigo commented Oct 6, 2016

Please answer these questions before submitting your issue. Thanks!

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

go version go1.7.1 darwin/amd64

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

macOS Sierra

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mateusz.gajewski/Desktop/Projects/"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.7.1/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.7.1/libexec/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/vn/xkx9_8zs1dxfqmvp2vclwh9h0000gn/T/go-build169132605=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin16.0.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

What did you do?

 go get -v -x github.com/svent/sift

What did you expect to see?

Installed sift

What did you see instead?

WORK=/var/folders/vn/xkx9_8zs1dxfqmvp2vclwh9h0000gn/T/go-build288978954
github.com/svent/sift
mkdir -p $WORK/github.com/svent/sift/_obj/
mkdir -p $WORK/github.com/svent/sift/_obj/exe/
cd /Users/mateusz.gajewski/Desktop/Projects/src/github.com/svent/sift
CGO_LDFLAGS="-g" "-O2" /usr/local/Cellar/go/1.7.1/libexec/pkg/tool/darwin_amd64/cgo -objdir $WORK/github.com/svent/sift/_obj/ -importpath github.com/svent/sift -- -I $WORK/github.com/svent/sift/_obj/ -std=gnu99 -O2 -funroll-loops matching_cgo.go
cd $WORK
clang -fdebug-prefix-map=a=b -c trivial.c
clang -gno-record-gcc-switches -c trivial.c
cd /Users/mateusz.gajewski/Desktop/Projects/src/github.com/svent/sift
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -I $WORK/github.com/svent/sift/_obj/ -g -O2 -std=gnu99 -O2 -funroll-loops -o $WORK/github.com/svent/sift/_obj/_cgo_main.o -c $WORK/github.com/svent/sift/_obj/_cgo_main.c
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -I $WORK/github.com/svent/sift/_obj/ -g -O2 -std=gnu99 -O2 -funroll-loops -o $WORK/github.com/svent/sift/_obj/_cgo_export.o -c $WORK/github.com/svent/sift/_obj/_cgo_export.c
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -I $WORK/github.com/svent/sift/_obj/ -g -O2 -std=gnu99 -O2 -funroll-loops -o $WORK/github.com/svent/sift/_obj/matching_cgo.cgo2.o -c $WORK/github.com/svent/sift/_obj/matching_cgo.cgo2.c
clang -I . -fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -fno-common -o $WORK/github.com/svent/sift/_obj/_cgo_.o $WORK/github.com/svent/sift/_obj/_cgo_main.o $WORK/github.com/svent/sift/_obj/_cgo_export.o $WORK/github.com/svent/sift/_obj/matching_cgo.cgo2.o -g -O2
# github.com/svent/sift
Undefined symbols for architecture x86_64:
  "_bytes_to_lower", referenced from:
      __cgo_79a82a9469b9_Cfunc_bytes_to_lower in matching_cgo.cgo2.o
     (maybe you meant: __cgo_79a82a9469b9_Cfunc_bytes_to_lower)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
@quentinmit
Copy link
Contributor

The .go source file contains:

inline void bytes_to_lower(const unsigned char *buf, unsigned char *out, size_t n) 

I think this is causing one part of the compile to think the function is inlined and so omitting the symbol in the object file, but obviously when _cgo_79a82a9469b9_Cfunc_bytes_to_lower was compiled, the function was not inlined and produced a reference to the symbol.

I'm not actually sure if this is supposed to work or not. I'm fairly sure it would be resolved by removing the "inline" designation from the functions in that file

/cc @ianlancetaylor

@quentinmit quentinmit changed the title Failed to build github.com/svent/sift on macOS Sierra cmd/cgo: inline functions produce link errors Oct 6, 2016
@quentinmit quentinmit added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Oct 6, 2016
@quentinmit quentinmit added this to the Go1.8 milestone Oct 6, 2016
@ianlancetaylor
Copy link
Contributor

Why are the clang invocations using the option -std=gnu99? That is not coming from Go, nor from the github package, as far as I can tell.

@ianlancetaylor
Copy link
Contributor

Oh, sorry, my apologies, it is in github.com/svent/sift/matching_cgo.go, I missed that.

@ianlancetaylor
Copy link
Contributor

I can recreate the problem on GNU/Linux if I used CC=clang.

@ianlancetaylor
Copy link
Contributor

Because the package is being compiled in C99 mode, a function that is plain inline (not extern inline or static inline) does not provide a definition if the function is not inlined. That is what is happening here. clang decides not to inline the function, so it discards the function definition. In effect, this kind of inline function is like a macro: if you don't define it nothing appears in the object file.

This is an issue that occurs in plain C as well. It has nothing to do with Go as such. The code only works if the compiler decides to inline all functions.

The simple fix is to change the comment in the matching_cgo.go to use static inline instead.

Closing because there is nothing to fix in Go.

@wendigo
Copy link
Author

wendigo commented Oct 6, 2016

Thx for the explanation @ianlancetaylor

@golang golang locked and limited conversation to collaborators Oct 6, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants