使用libc而不是glibc的Golang c-archive

时间:2018-12-26 15:56:30

标签: go linker cgo

有可能吗?

我想从C程序调用以下Go函数:

// package name: test
package main

import "C"

//export Start
func Start() {
    println("Hello world")
}

func main() {
}

我正在使用以下命令来构建档案

go build -buildmode=c-archive -o test.a main.go

使用gcc,我可以使这个C程序正常工作:

#include <stdio.h>
#include "test.h"

int main() {
  Start();
  return 0;
}

我正在使用以下命令来生成可执行文件:

gcc main.c sdlgotest.a -o main -lpthread

这对于amd64来说一切正常,但是我想在aarch64目标开发环境(使用libtransistor)中使用此归档文件

libtransistor构建系统使用LLVM,但它具有自己的一组标准包含(libc等),并且不使用glibc。

因此,当我尝试让libtransistor链接我的档案时,出现以下错误:

/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正在使用如下标记来编译代码:

-nostdlib -nostdlibinc -isystem /opt/libtransistor/include/

所以我想问题是链接器无法解析这些glibc符号。

有没有一种方法可以在没有这些glibc符号的情况下编译Go运行时,以便我可以按预期使用存档? (无需依赖GCC工具链或glibc)

2 个答案:

答案 0 :(得分:0)

来自the docs

  

可以分别通过CCCXX环境变量来更改默认的C和C ++编译器;这些环境变量可能包括命令行选项。

所以我会尝试类似的东西

$ CC=clang go build -buildmode=c-archive -o test.a main.go

看看会发生什么。

答案 1 :(得分:0)

运行go env并查看设置为go的环境参数列表。您可以根据需要更改某些参数。

以下是我用来从go程序构建共享dll的一些示例。

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