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/go: Allow skipping link phase of go build #9675

Closed
keithkml opened this issue Jan 23, 2015 · 6 comments
Closed

cmd/go: Allow skipping link phase of go build #9675

keithkml opened this issue Jan 23, 2015 · 6 comments

Comments

@keithkml
Copy link

I'm using Go in a somewhat unusual way in an Xcode Objective C/C++ project – I'm collecting the .o files out of go build's temp dir to produce a static library using ar. The static library is then linked into my project by Xcode's normal build process.

The goal of this system is to allow the majority of my project to be built in Xcode like it always has, but have the Go portion built by go build. This means I'd like Xcode to link the Go static library with the rest of my codebase.

So I have go build just compiling my Go code, solely so I can get those .o files – and that part works great. The problem is, go build fails during the link phase, because it's missing the C symbols used in my Go code via Cgo and import "C". It makes sense that the Go linker can't find these symbols, because they only exist in object files in Xcode's intermediate files dir.

So, I'd love to be able to tell go build to skip the link phase, since I don't actually need the fully linked binary, and thus the link failure is not meaningful.

In case it helps clarify, here's the output from go build:

# _/Users/keith/Code/GoTest/GoTest/go
Undefined symbols for architecture armv7:
  "_iosmain", referenced from:
      __cgo_8bff6e3df0ac_Cfunc_iosmain in main.cgo2.o
     (maybe you meant: __cgo_8bff6e3df0ac_Cfunc_iosmain)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

You can see that it can't find iosmain(), which is defined in a separate main.m which I don't want Go to see or compile.

@ianlancetaylor
Copy link
Contributor

You need to run the Go linker. That is what creates the .o files you want. Before the link step, the Go code is compiled into a Go-specific format that the system linker will not recognize. The error you see is coming from the external linker. You don't care what the external reports, since you are going to do your own link. So just run something like "go build -ldflags=-extld=/bin/true".

@keithkml
Copy link
Author

Hi @ianlancetaylor, thanks for the response. That looks like a good idea, unfortunately go build doesn't seem to get to that phase – the error appears to be happening earlier:

WORK=/var/folders/fy/0csn7mgd77v5_8rqw_7l4jdw0000gn/T/go-build609567644
_/Users/keith/Code/glue/glue/GoTest/GoTest/go
mkdir -p $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/
cd /Users/keith/Code/glue/glue/GoTest/GoTest/go
CGO_LDFLAGS="-g" "-O2" "-v" "-framework" "UIKit" "-framework" "Foundation" "-framework" "CoreGraphics" /Users/keith/Code/glue/glue/goios/pkg/tool/darwin_amd64/cgo -objdir $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/ -- -I $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/ main.go
/Users/keith/Code/glue/glue/goios/src/../misc/ios/clangwrap.sh -I . -fPIC -marm -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common -print-libgcc-file-name
/Users/keith/Code/glue/glue/goios/src/../misc/ios/clangwrap.sh -I . -fPIC -marm -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common -I $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/ -g -O2 -o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_main.o -c $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_main.c
/Users/keith/Code/glue/glue/goios/src/../misc/ios/clangwrap.sh -I . -fPIC -marm -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common -I $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/ -g -O2 -o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_export.o -c $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_export.c
/Users/keith/Code/glue/glue/goios/src/../misc/ios/clangwrap.sh -I . -fPIC -marm -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common -I $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/ -g -O2 -o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/main.cgo2.o -c $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/main.cgo2.c
/Users/keith/Code/glue/glue/goios/src/../misc/ios/clangwrap.sh -I . -fPIC -marm -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common -o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_.o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_main.o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_export.o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/main.cgo2.o -g -O2 -v -framework UIKit -framework Foundation -framework CoreGraphics
# _/Users/keith/Code/glue/glue/GoTest/GoTest/go
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: arm-apple-darwin14.0.0
Thread model: posix
 "/Applications/Xcode6.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch armv7 -iphoneos_version_min 5.1.0 -syslibroot /Applications/Xcode6.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.1.sdk -o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_.o -lcrt1.3.1.o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_main.o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/_cgo_export.o $WORK/_/Users/keith/Code/glue/glue/GoTest/GoTest/go/_obj/main.cgo2.o -framework UIKit -framework Foundation -framework CoreGraphics -lSystem /Applications/Xcode6.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/lib/darwin/libclang_rt.ios.a
Undefined symbols for architecture armv7:
  "_iosmain", referenced from:
      __cgo_9eb51abd5805_Cfunc_iosmain in main.cgo2.o
     (maybe you meant: __cgo_9eb51abd5805_Cfunc_iosmain)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

@keithkml
Copy link
Author

I get the same error whether I pass -ldflags=-extld=true. Even if I pass it nonsense flags:

GOARM=7 CGO_ENABLED=1 GOARCH=arm go build -work -x -v -ldflags '-sdfasdfasdf'

@keithkml
Copy link
Author

(sorry, accidentally submitted before finishing)

Even if I pass it those nonsense flags it produces the same error. It's clearly quitting before it ever calls the external linker.

@ianlancetaylor
Copy link
Contributor

That is a failure while handling a Go file that uses import "C". The go tool runs a small link in order to see which symbols will be defined by shared libraries. This link normally succeeds because the final link normally succeeds. We can't skip this link, though. We need to know that information in order to generate correct Go code in general. I don't think there is any clean way to handle this.

Perhaps you could provide dummy definitions of your symbols and #cgo LDFLAGS to pick up the dummy definitions. I don't know whether that would work or not.

@keithkml
Copy link
Author

Yep, my current workaround involves telling clang to tell ld to ignore _iosmain. Not very scalable though :)

/*
#cgo LDFLAGS: -Wl,-U,_iosmain -framework UIKit -framework Foundation -framework CoreGraphics
extern void iosmain(int argc, char *argv[]);
*/
import "C"

@mikioh mikioh changed the title Allow skipping link phase of go build cmd/go: Allow skipping link phase of go build Jan 24, 2015
@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