在musl上编译Diesel迁移时出现undefined symbol: strlcpy错误
解决
clux/muslrust 编译 diesel_migrations 时的 undefined symbol: strlcpy 错误 我帮你搞定这个编译错误——这个问题的核心原因很明确:strlcpy是macOS这类BSD系统自带的字符串处理函数,但**clux/muslrust使用的musl libc并没有实现这个非POSIX标准函数**。diesel_migrations依赖的底层组件(十有八九是SQLite的编译代码)在交叉编译时调用了它,所以链接阶段就报找不到符号了。
两种可靠解决方案(按推荐度排序)
方法1:手动补全 strlcpy 实现并链接
这种方法不需要修改依赖的源代码,直接在项目里补上缺失的函数,简单粗暴有效:
- 在项目的
src目录下新建strlcpy.c文件,写入兼容musl的实现:
#include <string.h> #include <stddef.h> size_t strlcpy(char *dst, const char *src, size_t size) { const size_t src_len = strlen(src); if (size == 0) { return src_len; } const size_t copy_len = (src_len < size - 1) ? src_len : (size - 1); memcpy(dst, src, copy_len); dst[copy_len] = '\0'; return src_len; }
- 在项目根目录创建
build.rs脚本,用来编译这个C文件:
fn main() { cc::Build::new() .file("src/strlcpy.c") .compile("strlcpy"); }
- 打开
Cargo.toml,添加cc作为构建依赖:
[build-dependencies] cc = "1.0"
- 重新用
clux/muslrust编译项目:
docker run --rm -v "$(pwd)":/volume clux/muslrust cargo build --release
方法2:调整SQLite编译选项(针对SQLite后端场景)
如果你的项目用的是SQLite数据库,问题大概率来自libsqlite3-sys编译自带SQLite时调用了strlcpy。可以通过环境变量强制SQLite用自己的内置实现替代:
编译时加上SQLITE3_FLAGS=-DHAVE_STRLCPY=0这个环境变量就行:
docker run --rm -v "$(pwd)":/volume -e SQLITE3_FLAGS="-DHAVE_STRLCPY=0" clux/muslrust cargo build --release
验证一下
编译完成后,你可以用file命令检查生成的二进制是不是真的musl静态链接:
file target/x86_64-unknown-linux-musl/release/你的二进制文件名
输出里应该能看到statically linked的字样,说明没问题了。
内容的提问来源于stack exchange,提问作者XAMPPRocky
相关产品推荐
相关产品推荐

