被 CGO 交叉编译折磨的一个周末

被 CGO 交叉编译折磨的一个周末

💡 原文中文,约2900字,阅读约需7分钟。
📝

内容提要

在使用 zig cc 交叉编译 CGO 项目时,rpath 设置失效,导致无法加载 .so 文件。最终通过 Docker buildx 在 ARM64 环境中编译,成功解决了该问题。

🎯

关键要点

  • 使用 zig cc 交叉编译 CGO 项目时,rpath 设置失效,导致无法加载 .so 文件。

  • RawWeb 是一个专注于个人网站的搜索引擎,使用 charabia Rust 库进行中文分词。

  • 选择 CGO 方式调用 Rust 代码,开发环境和服务器均为 ARM 架构。

  • 交叉编译 CGO 时需要设置不同的 .so 加载路径。

  • 升级 charabia 后,服务启动失败,报告找不到 .so 文件。

  • 通过 ldd 命令发现程序仍试图从本地绝对路径加载 .so,rpath 设置未生效。

  • 决定使用 Docker buildx 在 ARM64 环境中编译,绕过交叉编译问题。

  • Dockerfile 中包含构建 Rust 代码和 Go 应用的步骤。

  • 最终成功推送到线上并顺利运行。

延伸问答

使用 zig cc 交叉编译 CGO 项目时遇到的主要问题是什么?

主要问题是 rpath 设置失效,导致无法加载 .so 文件。

如何解决 zig cc 交叉编译时的 rpath 问题?

通过使用 Docker buildx 在 ARM64 环境中编译,绕过了交叉编译的问题。

在交叉编译 CGO 项目时,如何设置 .so 文件的加载路径?

可以通过 LDFLAGS 设置不同的 .so 加载路径,在编译时使用开发环境的路径,运行时使用二进制文件同级的 lib 目录。

为什么在升级 charabia 后服务启动失败?

因为升级后,程序仍试图从本地绝对路径加载 .so 文件,rpath 设置未生效。

Docker buildx 在解决交叉编译问题中有什么优势?

Docker buildx 可以在目标 ARM64 环境中直接编译,避免了交叉编译带来的复杂性。

在使用 zig cc 交叉编译时,如何检查 .so 文件的加载情况?

可以使用 ldd 命令检查二进制文件,查看程序是否正确加载 .so 文件。

➡️

继续阅读