go: cmd/link: cross compile from MacOS to Windows with CGO_ENABLED=1 and -buildmode=c-archive not working
What version of Go are you using (go version
)?
$ go version go version go1.20.2 darwin/arm64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/wsong/Library/Caches/go-build" GOENV="/Users/wsong/Library/Application Support/go/env" GOEXE=".exe" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="arm64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/wsong/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="windows" GOPATH="/Users/wsong/go" GOPRIVATE="" GOPROXY="https://goproxy.cn" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64" GOVCS="" GOVERSION="go1.20.2" GCCGO="gccgo" GOAMD64="v1" AR="x86_64-w64-mingw32-gcc" CC="x86_64-w64-mingw32-gcc" CXX="clang++" CGO_ENABLED="1" GOMOD="/Users/wsong/Development/test/go.mod" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config" GOGCCFLAGS="-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/var/folders/lr/s8_5072s6cs602ksv8tv5myh0000gn/T/go-build2849677897=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I have following files in my folder:
example/ go.mod test.c test.go ./example: main.c
wsong@Work: ~/Development/test $ cat go.mod module test go 1.20 wsong@Work: ~/Development/test $ cat test.c // Functions exported by Go. extern int Test(); int test() { Test(); return 0; } wsong@Work: ~/Development/test $ cat test.go package main //#include "errno.h" import "C" func main() {} //export Test func Test() C.int { return 0 } wsong@Work: ~/Development/test $ cat example/main.c extern int test(); int main(void) { test(); return 0; }
I run go build like this:
CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 go build -v -a -buildmode=c-archive .
Then go into example folder and run:
x86_64-w64-mingw32-gcc main.c ../test.a
What did you expect to see?
a.exe is generated.
What did you see instead?
/opt/homebrew/Cellar/mingw-w64/10.0.0_5/toolchain-x86_64/bin/x86_64-w64-mingw32-ld: /var/folders/lr/s8_5072s6cs602ksv8tv5myh0000gn/T//ccHcSIoc.o:main.c:(.text+0xe): undefined reference to `test’ collect2: error: ld returned 1 exit status
About this issue
- Original URL
- State: open
- Created a year ago
- Comments: 15 (9 by maintainers)
Commits related to this issue
- cmd/link: use path from "cc --print-prog-name ar" for c-archive buildmode When external linking with -buildmode=c-archive, the Go linker eventually invokes the "ar" tool to create the final archive l... — committed to Pryz/go by thanm a year ago
- env/corellium/ios: special case "--print-prog-name=ar" in clang wrapper Intercept the "--print-prog-name=ar" flag in the clang wrapper and return "ar" from the system path, as opposed to the "ar" sel... — committed to golang/build by thanm a year ago
Verified that the workaround works on my system.
Thanks
OK, I think I see what the issue is. I’ll send a CL tomorrow morning.
If you need a workaround for the time being, you can do this:
Problem here is that the Go linker is invoking the system “ar” instead of the cross-compiler’s “ar”.