Linux 64位环境下Android NDK r25c交叉编译armv7-a链接错误求助
跨平台C++项目Android交叉编译链接失败问题及解决方案
问题场景
在64位Linux主机上为armv7-a架构的Android平台开发跨平台C++项目,使用Android NDK r25c编译时,Makefile执行到生成最终可执行文件阶段失败——所有目标文件已成功生成,但链接步骤报错。
报错信息
clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Iinclude -c Packet.cpp -o ../bin/Packet.o -std=c++17 clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Iinclude -c Client.cpp -o ../bin/Client.o -std=c++17 clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Iinclude -c Server.cpp -o ../bin/Server.o -std=c++17 clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Iinclude -c Shell.cpp -o ../bin/Shell.o -std=c++17 clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Iinclude -c Filesystem.cpp -o ../bin/Filesystem.o -std=c++17 clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Iinclude -c client_main.cpp -o ../bin/client_main.o -std=c++17 clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Iinclude -c server_main.cpp -o ../bin/server_main.o -std=c++17 clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -o ../bin/cmain.out ../bin/Filesystem.o ../bin/Shell.o ../bin/Packet.o ../bin/Client.o ../bin/client_main.o /usr/bin/ld: unrecognised emulation mode: armelf_linux_eabi Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu i386pep i386pe elf64bpf clang-15: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [makefile:39: android] Error 1
目标文件状态
执行file命令查看生成的*.o文件,确认目标文件架构正确:
ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), not stripped
解决方案及最终Makefile
Android NDK仅通过下载解压安装,编译环境仅使用Linux终端(无Android Studio或Gradle),经多次尝试后完成交叉编译工具链配置,最终可用的Makefile如下:
export NDK_DIR = /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64 export ANDROID_CXX = $(NDK_DIR)/bin/clang++ export TARGET = --target=armv7a-linux-androideabi31 export SYSROOT = --sysroot=$(NDK_DIR)/sysroot export CPP_VERSION = -std=c++17 android: # 编译单个*.cpp文件为独立*.o文件 $(ANDROID_CXX) $(TARGET) $(SYSROOT) -Iinclude -c Packet.cpp -o ../bin/Packet.o $(CPP_VERSION) $(ANDROID_CXX) $(TARGET) $(SYSROOT) -Iinclude -c Client.cpp -o ../bin/Client.o $(CPP_VERSION) $(ANDROID_CXX) $(TARGET) $(SYSROOT) -Iinclude -c Server.cpp -o ../bin/Server.o $(CPP_VERSION) $(ANDROID_CXX) $(TARGET) $(SYSROOT) -Iinclude -c Shell.cpp -o ../bin/Shell.o $(CPP_VERSION) $(ANDROID_CXX) $(TARGET) $(SYSROOT) -Iinclude -c Filesystem.cpp -o ../bin/Filesystem.o $(CPP_VERSION) # 编译服务端和客户端两个入口文件为独立*.o文件 $(ANDROID_CXX) $(TARGET) $(SYSROOT) -Iinclude -c client_main.cpp -o ../bin/client_main.o $(CPP_VERSION) $(ANDROID_CXX) $(TARGET) $(SYSROOT) -Iinclude -c server_main.cpp -o ../bin/server_main.o $(CPP_VERSION) # 编译并链接所有目标文件为两个独立可执行文件(客户端和服务端) $(ANDROID_CXX) $(TARGET) $(SYSROOT) -o ../bin/cmain.out ../bin/Filesystem.o ../bin/Shell.o ../bin/Packet.o ../bin/Client.o ../bin/client_main.o $(ANDROID_CXX) $(TARGET) $(SYSROOT) -o ../bin/server_executable.out ../bin/Filesystem.o ../bin/Shell.o ../bin/Packet.o ../bin/Server.o ../bin/server_main.o # 删除单个*.o文件 rm -f ../bin/Android/Packet.o rm -f ../bin/Android/Client.o rm -f ../bin/Android/Server.o rm -f ../bin/Android/Shell.o rm -f ../bin/Android/Filesystem.o rm -f ../bin/Android/client_main.o rm -f ../bin/Android/server_main.o
内容的提问来源于stack exchange,提问作者Iman Abdollahzadeh
相关产品推荐
相关产品推荐

