在Golang项目中正确包含C库(按来源)

时间:2018-02-27 00:37:54

标签: go cgo

目前,我有以下源代码树:

client
|
|--cryptlib
|  |
|  |--cryptlib.so
|  |--cryptlib.a
|  |--<C sources>
|  |--Makefile
|
|--impl1
|  |--<C sources>
|  |--impl1.go
|  |--impl1_test.go
|
|--impl2
|  |--<C sources>
|  |--impl2.go
|  |--impl1_test.go
|
|--client.go
|--client_test.go

cryptlibimpl1同时使用impl2库,因此,impl1.goimpl2.go都会从以下cgo块开始:

/*
#cgo CFLAGS: -I. -I${SRCDIR}/../cryptlib -L${SRCDIR}/../cryptlib -lcryptlib -Ofast 
#cgo LDFLAGS: -L${SRCDIR}/../cryptlib -lcryptlib
*/
import "C"

这在尝试测试impl1_test.goimpl2_test.go时有效。

但是,在尝试运行位于client_test.go的测试时,我不断收到错误,声称无法找到cryptlib库。我认为这可能与${SRCDIR}在这种情况下./client使CFLAGSLDFLAGS路径的其余部分不正确(./client/../cryptolib这一事实有关)。

虽然这会导致重复,但我也尝试将cryptlib加入impl1impl2。尝试测试client_test.go时,此方法再次导致问题,因为组合二进制文件现在看到cryptlib中定义的相同函数的多个实例。

我应该如何正确构建源树和cgo标志,以便我的所有.go源文件都可以找到我的cryptlib库并编译?

1 个答案:

答案 0 :(得分:0)

来自cgo Godocs:

  

解析cgo指令时,会出现任何字符串   $ {SRCDIR}将被目录的绝对路径替换   包含源文件。

因此,对于client_testSRCDIR的目录级别更高,因此其CGO指令应如下所示:

/*
#cgo CFLAGS: -I. -I${SRCDIR}/cryptlib -L${SRCDIR}/cryptlib -lcryptlib -Ofast 
#cgo LDFLAGS: -L${SRCDIR}/cryptlib -lcryptlib
*/

就另一种方法而言,我通常做的是在系统库目录/usr/lib/中安装C库。这样我就不必担心相对引用,只需使用-lcryptlib