Open mewalig opened 3 years ago
Can you show us the code that you are trying to build?
Here's a simple example that has the same problem (at least for me).
test.go:
package main
// #include <stdlib.h>
import "C"
import (
"fmt"
"os"
"unsafe"
)
//export myExportedFunction
func myExportedFunction(c_str *C.char) C.int {
fmt.Println("hi")
return 0
}
func main() {
if len(os.Args) < 2 {
println("Usage: test <any_string>\n")
} else {
arg1 := os.Args[1]
arg1_c := C.CString(arg1)
defer C.free(unsafe.Pointer(arg1_c))
myExportedFunction(arg1_c)
}
}
test.c:
#include "test.h"
int main(int argc, char **argv) {
if(argc > 1)
myExportedFunction(argv[1]);
return 0;
}
What happens if you use go build -buildmode=c-archive -ldflags=-extar=x86_64-w64-mingw32-ar ...
? (Keep all the environment variable setting also, just add the -ldflags=-extar
flag.)
That worked. You are the man! Thank you.
BTW: is there documentation that describes this necessary step, which I missed? In case it answers any other future questions/issues I might otherwise run into
I'm going to reopen this to get better documentation.
We should also consider supporting an AR
environment variable.
We should also consider supporting an AR environment variable.
There appears to already be an AR
env var?
https://github.com/golang/go/blob/4c1a7ab49c4c68907bc7f7f7f776edd9116584a5/src/cmd/go/internal/envcmd/env.go#L112
Looks like it might just be a few lines change to get ld
to use the AR
env
https://github.com/golang/go/blob/972e8839254d59dc04a1193c4c9633a74595a2e7/src/cmd/link/internal/ld/lib.go#L1218
What version of Go are you using (
go version
)?go version go1.16.3 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?darwin + amd64
What did you do?
I am compiling Go into a static archive to be called with C code. It works when I compile for the native platform. It does not work when I try to cross-compile for Windows using mingw64
Works:
cross-compile C for Win using mingw64 (no Go code) (to confirm that my C cross-compile toolchain works)
x86_64-w64-mingw32-gcc only_c.c -o only_c.exe
native compile: Go to static archive, exporting a function
myExportedFunction
, called by C executable:go build -buildmode=c-archive test.go
# ( exports myExportedFunction )clang test.c test.a -o test
# ( test.c calls myExportedFunction )No errors or warnings:
CC=x86_64-w64-mingw32-gcc GOOS=windows CGO_ENABLED=1 go build -o test.w64a -buildmode=c-archive test.go
CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CPP=x86_64-w64-mingw32-cpp RANLIB=x86_64-w64-mingw32-ranlib AR=x86_64-w64-mingw32-ar LIBTOOL=/opt/mingw64/bin/libtool GOARCH=amd64 GOOS=windows CGO_ENABLED=1 go build -o test.w64a -buildmode=c-archive test.go
Fails:
x86_64-w64-mingw32-gcc test.c test.w64a -o test.exe
/.../x86_64-w64-mingw32-ld: /.../ccmb8owx.o:test.c:(.text+0x29): undefined reference to "myExportedFunction"
What did you expect to see?
No error message, and test.exe file created
What did you see instead?
Error message