Rust dylib 兔子洞 | David Lattimore

主要观点:

  • Bevy 是流行的 Rust 游戏引擎,其较大且编译时间是问题,可通过启用可选功能将大部分 Bevy 编译为动态库以加快迭代。
  • 实验测试非优化构建下链接时间及生成的.so 文件效果,关闭调试信息后优化未必然使链接更快。
  • 非优化构建默认启用-Z share-generics导致导出符号增多,多数额外符号为未内联函数。
  • 动态链接时运行时可查找其他共享对象提供的符号,rust 通常设置在加载时绑定符号。
  • 控制共享对象导出符号需通过版本脚本,多数带有GLOB_DAT重定位的符号是动态库自身定义的。
  • GNU ld 对直接引用受保护符号有限制,不同编译器在构建可执行文件和共享对象时对符号引用方式不同,混合使用可能导致问题。
  • Rust 编译器默认使用 LLVM 进行代码生成,改变符号可见性为受保护时与 GNU ld 存在不兼容。
  • Windows 采用不同方式处理可能来自共享对象的符号。
  • 更改 rustc 为发出所有 Rust 修饰符号的受保护可见性在 LLVM/LLD 环境中可行,但与 GNU ld 不兼容。

关键信息:

  • 测试相关命令:cargo run --features bevy/dynamic_linking
  • 不同链接器的链接时间对比:lld (18) 1975ms、mold (2.32.1) 1763ms、wild 895ms(GNU ld 超过 10s 未纳入),设置opt-level = 2后链接时间大幅下降。
  • 版本脚本示例控制符号导出。
  • 不同可见性对符号可访问性及可重写性的影响。
  • 受保护符号在不同编译器下的代码生成差异及问题。

重要细节:

  • 实验中对调试构建和非优化构建的设置及结果。
  • 不同编译器处理变量和函数访问的方式及差异。
  • 关于共享对象与不同编译器组合使用时可能出现的变量副本等问题。
  • binutils 2.40 对 GNU ld 问题的修复及相关错误报告。
  • 关于在不同系统和编译器环境下处理共享对象和符号可见性的讨论及后续工作方向。
阅读 13
0 条评论