交叉编译Rust到Android时链接器无法找到静态C库符号
交叉编译Rust到x86_64 Android时链接静态库espeak-ng出现符号未定义问题
问题现象
链接阶段出现如下错误:
ld: error: undefined symbol: espeak_Initialize >>> referenced by lib.rs:108 (packages/espeak/src/lib.rs:108) >>> /target/x86_64-linux-android/debug/deps/oratio_espeak-6fba08adc959e6d8.3x6nmh9h9fre8r93.rcgu.o:(oratio_espeak::initialize::h403ba8dd7c5de0ec) clang140: error: linker command failed with exit code 1 (use -v to see invocation)
已验证的关键信息
- 链接器能正确定位到库:修改
-L/-l参数会触发“无法找到库”的错误,说明路径配置无误 - 静态库确实包含目标符号:
$ nm libespeak-ng.a | grep espeak_Initialize 0000000000000000 T espeak_Initialize $ objdump -f libespeak-ng.a libespeak-ng.a(libespeak_ng_la-case.o): file format elf64-x86-64 architecture: x86_64 start address: 0x0000000000000000 [repeat for all object files...]
交叉编译espeak-ng的命令
使用Android NDK编译静态库的命令如下:
PATH=$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin:$PATH CC="x86_64-linux-android33-clang" CXX="x86_64-linux-android33-clang++" ./autogen.sh ./configure --host=aarch64-apple-darwin --target=x86_64-linux-android make
构建与链接参数
构建命令
$ cross test --target x86_64-linux-android --config target.x86_64-linux-android.linker="'/android-ndk/bin/x86_64-linux-android33-clang'" --config target.x86_64-linux-android.ar="'/android-ndk/bin/x86_64-linux-android-ar'"
注:也尝试过不带--config参数的情况,此时链接器变为cc,但错误相同。
链接器完整调用参数(简化后)
LC_ALL="C" PATH="/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/android-ndk/bin:/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin" VSLANG="1033" "/android-ndk/bin/x86_64-linux-android33-clang" "-m64" "/tmp/rustcEr0LI7/symbols.o" "/target/x86_64-linux-android/debug/deps/oratio_espeak-74e896619faec8e7.119cce293ejvq2cd.rcgu.o" [other similar .rcgu.o omitted for brevity] "/target/x86_64-linux-android/debug/deps/oratio_espeak-74e896619faec8e7.2s376qmbbifeevz2.rcgu.o" "-Wl,--as-needed" "-L" "/target/x86_64-linux-android/debug/deps" "-L" "/target/debug/deps" "-L" "/target/x86_64-linux-android/debug/build/oratio-espeak-7547cefa827890c5/out/espeak-ng/x86_64-linux-android" # 该目录包含libespeak-ng.a "-L" "/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-linux-android/lib" "-lespeak-ng" "-Wl,-Bstatic" "/target/x86_64-linux-android/debug/deps/libespeakng_sys-70bc6650c0b39573.rlib" "/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-linux-android/lib/libtest-e3fab4d163e91148.rlib" [other similar .rlib omitted for brevity] "/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-linux-android/lib/librustc_std_workspace_std-74e842bbf3699e1d.rlib" "/target/x86_64-linux-android/debug/deps/libparking_lot-27cc7ea2042fb770.rlib" [other similar .rlib omitted for brevity] "/target/x86_64-linux-android/debug/deps/libeither-c29c058d37529903.rlib" "/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-linux-android/lib/libstd-37d05f9f3fc29d7b.rlib" [other similar .rlib omitted for brevity] "/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-linux-android/lib/libcompiler_builtins-3a801941068d9a2c.rlib" "-Wl,-Bdynamic" "-lespeak-ng" "-ldl" "-llog" "-lunwind" "-ldl" "-lm" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/Users/arthur/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-linux-android/lib" "-o" "/target/x86_64-linux-android/debug/deps/oratio_espeak-74e896619faec8e7" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs"
疑问
在库已被找到且确实包含目标符号的情况下,哪些原因会导致符号缺失?
内容的提问来源于stack exchange,提问作者Arthur Chaloin
相关产品推荐
相关产品推荐

