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



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

理由

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

如果project A可以在没有 Go 运行时定义的情况下生成其库,则可以轻松解决project Cproject D面临的问题。Project C可以与libA.a链接.Project D将链接到libA.alibA2.a和一些包含所有 Go 运行时定义的libGo.a

我尝试过:

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

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

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

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

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

如果您的C 代码不介意与-Bsymbolic链接,您可以尝试添加c-archive-Wl,-Bsymbolic来构建包含 Go 代码的每个共享库。

祝你好运。

最新更新