一段时间以来,我一直在尝试针对 Musl 进行编译。我的目标是制作一个游戏引擎二进制文件,它可以使用相同的二进制文件在尽可能多的 x86_64 Linux 发行版上执行。
问题是,链接器 x86_64-linux-musl-gcc 找不到 pthread_mutex_init 等符号,即使 pthread 按照 Musl 设计嵌入到 Musl libc 中也是如此。
我正在用 Rust 构建引擎并使用命令
cargo build --release --target=x86_64-unknown-linux-musl --bin catgirl-engine
来调试编译步骤。
我创建了一个Asciinema Recording来演示编译失败。
静态误差为:
= note: /home/alexis/Desktop/game/build/x86-64-linux-musl-cross/bin/../lib/gcc/x86_64-linux-musl/9.4.0/../../../../x86_64-linux-musl/bin/ld: /home/alexis/Desktop/game/android/app/jni/SDL/build/libSDL2.a(SDL_sysmutex.c.o): undefined reference to symbol 'pthread_mutex_init'
/home/alexis/Desktop/game/build/x86-64-linux-musl-cross/bin/../lib/gcc/x86_64-linux-musl/9.4.0/../../../../x86_64-linux-musl/bin/ld: /home/alexis/Desktop/game/build/x86-64-linux-musl-cross/bin/../x86_64-linux-musl/lib/libc.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
在我发现 pthread 嵌入在 Musl 的 libc 中之前,我尝试链接到 lib 目录并为标头指定 include 目录。我什至尝试链接 Debian 软件包 libc6-dev-amd64-cross 和 musl-dev 中的文件。
我期望在不依赖于特定版本的 libc 的情况下编译引擎。这是为了提高大规模可移植性,因为那时我只需要用自定义版本的 SDL、SDL_image 和 SDL_ttf 运送我的引擎。
我已经成功构建了 Android 引擎,并将 SDL、SDL_image 和 SDL_ttf 与应用程序的 Android 版本打包在一起,所以我想对 x86_64 版本做同样的事情。
当我了解到 Github Actions 上的 glibc 版本比 Debian 提供的要新得多时,我才第一次发现这个问题。
这是我的 ~/.cargo/config
[target.x86_64-unknown-linux-musl]
ar = "/home/alexis/Desktop/game/build/x86-64-linux-musl-cross/bin/x86_64-linux-musl-ar"
linker = "/home/alexis/Desktop/game/build/x86-64-linux-musl-cross/bin/x86_64-linux-musl-gcc"
rustflags = ["-L/home/alexis/Desktop/game/android/app/jni/SDL/build", "-L/home/alexis/Desktop/game/android/app/jni/SDL_image/build", "-L/home/alexis/Desktop/game/android/app/jni/SDL_ttf/build", "-L/home/alexis/Desktop/game/build/x86-64-linux-musl-cross/lib", "-L/home/alexis/Desktop/game/build/x86-64-linux-musl-cross/x86_64-linux-musl/lib", "-Clink-arg=-Wl,-rpath,.,-rpath-link,/home/alexis/Desktop/game/android/app/jni/SDL/build", "-Clink-arg=-L/home/alexis/Desktop/game/build/x86-64-linux-musl-cross/x86_64-linux-musl/lib", "-Clink-arg=-lpthread"]
我对 x86_64-linux-musl-cross 的最后一次构建是基于this commit。由于 Github Actions(通过 Ubuntu)使用比我的笔记本电脑(最新版本的 Debian)更新的 libc,我正在为我的本地建筑使用 x86_64-linux-musl-cross 的本地构建,并为远程使用相同提交的 Github 构建建筑。
错误,
undefined reference to pthread_mutex_init
,表明Musl没有直接提供pthreads
。
Musl 应该是一个支持最小功能集的“轻量级”库。它确实包括 pthreads 支持,但不是作为核心库功能,而是作为单独的库提供,
libpthread
.
要链接
pthread
函数,您需要将 -lpthread
标志添加到链接器命令中:
cargo build --release --target=x86_64-unknown-linux-musl --bin catgirl-engine -C link-args=-lpthread