Go包与C库的链接

Go包与C库的链接,c,go,linkage,cgo,C,Go,Linkage,Cgo,我希望这是一个基本问题。我正在尝试构建一个Go包,其中包含用C编写的库中的函数。结构基本如下: package too /* #cgo LDFLAGS: -L/usr/local/lib include -lbar #include mybar.h */ import "C" func MyGoWrapper () { C.orig_func() } 运行go build foo.go失败,因为orig_func有一个“未定义的引用”。注意,标题是mybar.h;我为原始库中未包含的o

我希望这是一个基本问题。我正在尝试构建一个Go包,其中包含用C编写的库中的函数。结构基本如下:

package too

/*
#cgo LDFLAGS: -L/usr/local/lib include -lbar
#include mybar.h
*/
import "C"

func MyGoWrapper () {
  C.orig_func()
}

运行
go build foo.go
失败,因为
orig_func
有一个“未定义的引用”。注意,标题是
mybar.h
;我为原始库中未包含的
orig_func
创建了一个原型。我是否需要先重新编译库(包括此头文件),然后再将其链接到Go构建?还是我完全误解了其他内容?

当链接到外部库时,您确实需要为您的目标体系结构单独编译它
cgo
不能代替
配置
/
生成
(或其他)来编译库;它只知道如何在包目录中构建一些
.c
文件,而库的构建过程可能更复杂


我不太确定交叉编译时如何在外部库中完成链接这一更大的任务(我也不确定您已经做了什么)。您可能希望使用一些环境变量集构建Go工具链,如中所述:

要在交叉编译生成期间启用cgo,请将cgo_设置为ENABLED 使用make.bash构建Go工具时,将环境变量设置为1。 另外,将CC_FOR_TARGET设置为目标的C交叉编译器。抄送遗嘱 用于为主机进行编译

生成Go工具后,在运行Go命令时,为_目标抄送_ 被忽略了。运行make.bash时,_目标的CC_值为 默认编译器。但是,您可以设置环境变量CC,而不是 CC_FOR_TARGET,用于在运行go工具时控制编译器

CXXFIOFIORATION以类似的方式工作,C++代码。 该bug还提到有人使用了

-ldflags=“-extld=$(CC)”
(其中
$(CC)
是他们想要使用的交叉编译器的名称)


在您的示例代码中,有一个显式的
-L/usr/local/lib
,我认为这行不通:我认为,当您为目标构建库时,您会希望将它们放在与主机arch的
lib
不同的目录中。例如,使用
/usr/local/arm linux
前缀或在某些地方安装\u root。

我没有引用,但我认为在使用cgo时,Go不允许交叉编译。然而,要做到这一点,您需要一些复杂的设置,可能是环境变量
CGO\u ENABLED=1
CC\u FOR_TARGET
/
CXX\u FOR_TARGET
(gcc/g++FOR TARGET platform),甚至可能是类似于
-ldflags=“-extld=$(CC)”
传递给
go build
。这不是一个答案,因为我不知道这是不是真的——我完全是根据那里的评论来回答的。要想让
-lbar
工作,你需要为你的目标arch安装
libbar
go build
不会为你构建和安装它),我怀疑
-L/usr/local/lib
——我认为您可能会在其他地方有一个单独的
lib/
,库的目标是其他体系结构。(如果库非常独立,解决链接器兴奋的一种方法是将整个库的源代码转储到您的包中,比如说,像这样。)@我确实以go-sqlite3为例,但我需要的库太大,无法像这样转储到存储库中。这是对我最初提出的问题的一个很好的回答。然而,在我的例子中,交叉编译并不是一个问题。我会更新更多细节;至于现在,@twoo,您已经对使用cgo进行交叉编译提供了极好的解释。谢谢