交叉编译共享库

5

我想知道是否可以用Go交叉编译共享库,如果可以的话,应该如何操作?比如说,我有这样的代码:

package main

import "C"

//export DoubleIt
func DoubleIt(x int) int {
    return x * 2
}

func main() {}

src/doubler/main.go 中。在 Mac 上我可以运行

go build -o libdoubler.dylib -buildmode=c-shared doubler

要获取名为libdoubler.dylib的共享库。在Linux上类似,只需使用扩展名.so

现在我想将Linux作为构建我的库(用于Mac和Windows)的主要平台。我有哪些选择?

GOOS设置为darwin并在Linux上运行上述命令,我得到:

can't load package: package doubler: no buildable Go source files in /home/patrick/Desktop/go/src/doubler

有什么想法吗?
2个回答

7
你面临的问题实际上不是关于编译共享库或可执行文件,而是使用cgo并尝试交叉编译。(但如果你想要一个库而不是可执行文件,包名不应该是main。)
在交叉编译时,默认情况下会禁用cgo。如果添加环境变量CGO_ENABLED=1,则你的示例将正常工作:
CGO_ENABLED=1 GOOS=darwin go build -o libdoubler.dylib -buildmode=c-shared doubler

请记住,在交叉编译时使用cgo会很麻烦。您需要确保目标平台的C库已经在主机上准备好。如果不是必需的,请避免使用cgo。如果必须使用,您可以考虑在目标机器上进行编译,而不是处理使用cgo进行交叉编译的维护工作。

说“在我的电脑上无法工作”。ld无法识别标志,gcc返回退出状态1。 - Uvelichitel
package main-buildmode=c-shared 不能同时使用。我认为提问者已经意识到这个问题,因为另一个答案已经指出了这个问题。我已经编辑了我的回答以澄清这一点。非常感谢! - hasanyasin
我一直拼错CGO_ENABLED...现在它“工作”了,意思是不再抛出任何错误。但我希望解决方案不需要安装交叉编译环境。 - topskip
@hasanyasin,我在OS X上使用package main没有任何问题。 - topskip
如果包是主要的,我们在Linux机器上使用GOOS=darwin交叉编译,并希望它生成一个共享包,则链接会失败,就像uvelichitel提到的那样。如果您使用纯Go,则交叉编译非常容易。如果您使用非Go库,则无论如何都必须拥有这些库以用于目标平台。没有乐高积木就不能玩乐高。 :) - hasanyasin
不知何故(Go 1.9,macOS 10.13),只有当我将包命名为“main”时才能正常工作。否则,我会得到一个“current ar archive”而不是“Mach-O 64位动态链接共享库x86_64”。 - topskip

0

构建客户端时,请使用:

package main 

...然而构建一个库使用:

package mylibname

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接