gcc - 从一个编译器版本到另一个编译器版本的符号重定位

我正在编译一个静态库,我们称它为 static.a,它稍后由共享库 shared.so 和最终的可执行二进制文件链接(shared.so 仅使用 static.a 中的几个函数,可能稍后这可以进一步拆分)。如果我尝试使用 gcc 7.4 编译它,我会收到此链接器错误:

/usr/bin/ld: ../../static.a(file.cpp.o): relocation R_X86_64_TPOFF32 against symbol `_ZGVZN6spdlog7details2os9thread_idEvE3tid' can not be used when making a shared object; recompile with -fPIC

我决定也尝试 gcc 9.1,这个错误不再出现。

  1. 在构建将在共享库中使用的静态库时,我应该始终使用 -fpic 吗?我知道 fpic 会增加一些开销。
  2. 为什么较新版本的 gcc 可以在共享库中重新定位 static.a 的符号?这样安全吗?

谢谢。

最佳答案

共享库中的所有代码都应使用 -fPIC 进行编译,因此您的静态库也应该如此。 -fPIC 确实会带来开销,但在很大程度上可以通过 -fno-semantic-interposition 等选项来减轻开销。和/或 -fvisibility=hidden .

您看到的错误来自链接器,因此较新的 GCC 似乎没有使用有问题的重定位。您可以检查生成的程序集以找出生成的代码中的差异。

https://stackoverflow.com/questions/57053940/

相关文章:

c# - C# 中 C++ 结构化绑定(bind)的模拟

reactjs - 在 nextjs 中,对象类型从服务器端更改为客户端

flutter - 如何修复 flutter 上的 "A RenderFlex overflowed

jenkins - BlueOcean编辑器 "scm"输入什么

c# - 502 Bad Gateway nginx/1.14.1 elasticbeanstalk

reactjs - Babel 不从当前目录上方的文件转译 JSX

spring-boot - spring boot 微服务 docker 实现中 google oa

reactjs - 如何使用 Jest 和 Enzyme 在 nextjs 应用程序中编写单元测试

angular - Mat-select 滚动不跳转到选定的 mat-option

amazon-web-services - 如何在数据加载前截断 AWS Glue 作业中的 RDS