c - Go/Cgo:生成没有 Go 运行时函数定义的静态库
问题描述
有没有办法从 Go 代码生成 C 静态库,但没有 Go 运行时函数定义?
理由:
Project A
go build -buildmode=c-archive
用,创建一个 C 静态库libA.a
。- 效果很好:
project B
使用纯 C 并且能够轻松创建可执行文件,静态链接libA.a
,一切都很好。 - 问题 1:
project C
碰巧也使用 Go,但想libA.a
用作常规 C 库。现在它有一个链接问题:像 eg 这样的 Go 运行时函数_cgo_panic
现在在project C
运行时(因为它使用 Go)和libA.a
. - 问题 2:
project D
使用纯 C,与 B 相同。但它想使用来自 的两个不同库project A
,例如libA.a
和 somelibA2.a
。遗憾的是,它也没有链接,因为 Go 运行时函数现在都定义在libA.a
和libA2.a
.
如果可以在没有 Go 运行时定义的情况下生成其库,则可以project C
轻松project D
解决所面临的问题。可以链接到. 将链接到,和一些将包含所有 Go 运行时内容的定义。project A
Project C
libA.a
Project D
libA.a
libA2.a
libGo.a
我尝试了什么:
- 在“项目 C”级别使用链接器标志,例如
-Wl,--allow-multiple-definition
. 现在它的构建失败,并显示一条神秘的消息“函数符号表未按程序计数器排序”。 - 从“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
解决方案
-buildmode=c-archive
正如您所发现的,在当前的实现中,多次使用并将结果放入多个共享库是行不通的。基本问题是 Go 运行时必须只有一个,但你有多个运行时。使用-buildmode=c-archive
时无法隔离不同的运行时。
这些-buildmode=c-shared
库的不同之处buildmode=c-archive
在于它们是用它构建的,-Bsymbolic
它强制所有本地引用都是本地的。效果是我们有多个 Go 运行时,但它们不相互引用,所以没有混淆。
如果您的 C 代码不介意-Wl,-Bsymbolic
与.c-archive
-Bsymbolic
祝你好运。
推荐阅读
- excel - Range类的间歇性“运行时错误'1004'PasteSpecial方法失败
- ruby-on-rails - 复杂 Rails 表单最佳实践
- database - Kusto 查询列上的优先排序
- java - 如何在 groovy 或 java 中保存 dbf 文件?
- c++ - 我可以打印到始终显示的 Windows 控制台数据吗?
- typescript - typescript-eslint 检查是否所有变量都分配了数据类型
- python - 创建火车和测试数据加载器
- python - 列出 setup.py 中已安装的软件包
- mysql - MySQL Select 和 IF() 语句
- c# - 如何更改在 OAuth Authentication c# .net core 3.1 上获取令牌的方式