Is it possible?
I have the following Go function I'd like to call from a C program:
// package name: test
package main
import "C"
//export Start
func Start() {
println("Hello world")
}
func main() {
}
I'm using the following command to build the archive
go build -buildmode=c-archive -o test.a main.go
Using gcc I can get this C program working:
#include <stdio.h>
#include "test.h"
int main() {
Start();
return 0;
}
I'm using the following command to build the executable:
gcc main.c sdlgotest.a -o main -lpthread
This all works fine for amd64, but I'd like to use this archive in a aarch64 targed development environment (using libtransistor)
libtransistor build system uses LLVM but it has it's own set of standard includes (libc, etc.) and it doesn't use glibc.
So when I'm trying to get libtransistor to link my archive I get the following errors:
/usr/lib/llvm-5.0/bin/ld.lld: error: undefined symbol: stderr
>>> referenced by gcc_libinit.c:29
>>> 000006.o:(x_cgo_sys_thread_create) in archive ./sdlgotest.a
/usr/lib/llvm-5.0/bin/ld.lld: error: undefined symbol: stderr
>>> referenced by gcc_libinit.c:29
>>> 000006.o:(x_cgo_sys_thread_create) in archive ./sdlgotest.a
libtransistor by the way is compiling the code with flags like this:
-nostdlib -nostdlibinc -isystem /opt/libtransistor/include/
So I guess the problem is that the linker can't resolve those glibc symbols.
Is there a way to compile the Go runtime without those glibc symbols so I can use the archive like I intend to? (without relying on GCC toolchain or glibc)
From the docs:
The default C and C++ compilers may be changed by the
CC
andCXX
environment variables, respectively; those environment variables may include command line options.
So I'd try something like
$ CC=clang go build -buildmode=c-archive -o test.a main.go
and see what happens.
Run go env
and see the list of env parameters set to go. You can change certain parameters based on what you need.
Following are some of the samples that I have used to build a shared dll from go program.
GOARCH=386 GOOS=windows CGO_ENABLED=1 GOPATH=`pwd` CC=i686-w64-mingw32-gcc go build -o go-shared-lib.dll -buildmode=c-shared go-shared-libs
GOARCH=amd64 GOOS=windows CGO_ENABLED=1 GOPATH=`pwd` CC=x86_64-w64-mingw32-gcc go build -o go-shared-lib.dll -buildmode=c-shared go-shared-libs