【发布时间】:2021-04-24 13:58:06
【问题描述】:
有没有办法从 Go 代码生成 C 静态库,但没有 Go 运行时函数定义?
理由:
-
Project A使用go build -buildmode=c-archive、libA.a创建一个 C 静态库。 - 运行良好:
project B使用纯 C,能够轻松创建可执行文件,与libA.a静态链接,一切都很好。 - 问题 1:
project C恰好也使用 Go,但想将libA.a用作常规 C 库。现在它有一个链接问题:Go 运行时函数,例如 e.g._cgo_panic现在在project C运行时(因为它使用 Go)和libA.a中定义。 - 问题 2:
project D使用纯 C,与 B 相同。但它想使用来自project A的两个不同库,例如libA.a和一些libA2.a。遗憾的是,它也没有链接,因为 Go 运行时函数现在在libA.a和libA2.a中定义。
project C 和 project D 面临的问题可以很容易地解决,如果 project A 可以在没有 Go 运行时定义的情况下生成其库。 Project C 可以与 libA.a 链接。 Project D 将与 libA.a、libA2.a 和一些 libGo.a 链接,它们将包含所有 Go 运行时内容的定义。
我尝试了什么:
- 在“项目 C”级别使用链接器标志,例如
-Wl,--allow-multiple-definition。现在它的构建失败并显示一条神秘消息“function symbol table not sorted by program counter”。 - 从“libA.a”中手动删除
go.o(因为它只是一个“ar”存档):不起作用,因为“go.o”还包含我导出函数的实现,所以我删除了太多. - 使用
go build -buildmode=c-shared。正如预期的那样,它生成了一个使用另一种格式的动态库,所以我不能直接将它用作静态库。
客户端的任何解决方案(例如在project C 的链接阶段找到忽略重复定义的适当方法)也将被视为有效答案。
如果提供足够的证据,我也可以接受否定答案(没有解决方案)。
更新:查看相关问题Is there a way to include multiple c-archive packages in a single binary
【问题讨论】:
-
Go 代码需要 go runtime,不支持加载 go runtime 的多个实例。你不能以这种方式使用 go。
-
谢谢,这可能是答案。这在任何地方都有记录吗?
-
据我所知,它只是通过遗漏记录的,除非特别允许,否则我不希望它起作用。让多个 Go 运行时实例在同一个进程空间内协作并非易事。
标签: c go linker static-libraries cgo