Go/Cgo:生成没有 Go 运行时函数定义的静态库

Ale*_*der 5 c linker static-libraries go cgo

有没有办法从 Go 代码生成 C 静态库,但没有 Go 运行时函数定义

理由

  • Project Ago build -buildmode=c-archive使用,创建一个 C 静态库libA.a
  • 效果很好:project B使用纯 C 语言,能够轻松创建可执行文件,静态链接libA.a,一切都很好。
  • 问题1:project C碰巧也使用Go,但想用作libA.a 常规C库。现在它有一个链接问题:Go 运行时函数(例如eg)_cgo_panic现在在project C运行时(因为它使用Go)和libA.a.
  • 问题2:project D使用纯C,与B相同。但它想使用两个不同的库project A,例如libA.a和一些libA2.a。遗憾的是,它也没有链接,因为 Go 运行时函数现在都在 和 中libA.a定义libA2.a

如果可以生成不包含 Go 运行时定义的库,project C则 和所面临的问题project D可以轻松解决。可以直接链接到. 会链接到,有些会包含所有 Go 运行时内容的定义。project AProject ClibA.aProject DlibA.alibA2.alibGo.a

我尝试过的:

  • 在“项目 C”级别使用链接器标志,例如-Wl,--allow-multiple-definition. 现在它的构建失败并出现一条神秘消息“函数符号表未按程序计数器排序”。
  • 手动go.o从“libA.a”中删除(因为它只是一个“ar”存档):不起作用,因为“go.o”还包含我导出的函数的实现,所以我删除了太多。
  • 使用go build -buildmode=c-shared。正如预期的那样,它生成了一个使用另一种格式的动态库,因此我无法直接将其用作静态库。

客户端的任何解决方案(例如找到一种适当的方法来忽略 的链接阶段的重复定义project C)也将被视为有效答案。
如果它提供了足够的证据,我也可以接受否定的答案(无解决方案)。

更新:查看相关问题有没有办法在单个二进制文件中包含多个 c-archive 包

syn*_*aqx 0

-buildmode=c-archive正如您所发现的,在当前的实现中,多次使用并将结果放入多个共享库中是行不通的。本质问题是必须只有一个 Go 运行时,但你有多个运行时。使用时-buildmode=c-archive无法隔离不同的运行时。

这些-buildmode=c-shared库的不同之处buildmode=c-archive在于,它们的构建方式-Bsymbolic强制所有本地引用都是本地的。效果是我们有多个 Go 运行时,但它们不互相引用,因此不会造成混淆。

如果您的 C代码介意与.-Wl,-Bsymbolicc-archive-Bsymbolic

祝你好运。