英文:
Clang++ /usr/bin/ld: unrecognised emulation mode: armelf_linux_eabi
问题
我正在为 Android 上的 armv7-a 架构在 Linux 64 位主机上开发一个跨平台 C++ 项目,使用的是 Android NDK r25c,并且已经在构建最终可执行文件时遇到了以下错误输出:
/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
所有的 *.o 文件都已经构建完成,运行 file
命令查看它们的输出如下:
ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), not stripped
但是将所有的 *.o 文件链接在一起以创建可执行文件的最后一个命令失败了。是否有人有任何想法?
这是我的解决方案(如果有人感兴趣的话):
Android NDK 的安装只是下载和解压缩 zip 文件。为了设置交叉编译工具链,我会参考我在大量试错后制定的 "Solution",因为实际上我无法在任何地方找到任何帮助。构建环境只是 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)
# 编译服务器和客户端的两个入口点,并将它们的 *.cpp 文件转换为单独的 *.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)
# 编译并链接所有对象文件为两个单独的 *.out 文件(一个用于客户端,一个用于服务器)
$(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
希望这能帮助解决你的问题。
英文:
I am developing a cross platform C++
project for Android with armv7-a
architecture on Linux 64 bit
as host machine. I use Android NDK r25c
and stopped to build the final executable file by this output from my 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
All *.o
files have been constructed and running file
command on them gives:
> ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), not stripped
But the very last command to link all *.o
files together and create the executable file fails.
Does anybody have any idea?
This is after my own solution (in case anyone is interested):
The installation of Android NDK was just downloading and extraction of the zip file. To set up the cross compiling toolchains, I would refer to the Solution
that I made after a lot of trial and error
because actually I could not find any assistance anywhere. The build environment was nothing but liunx terminal (no Android studio nor Gradle).
And this is my 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:
# compile single *.cpp files into separate *.o files
$(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)
# compile two entry points for server and client and convert their *.cpp files into separate *.o files
$(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)
# compile and link all object files into two separate *.out files (one for client and one for server)
$(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
# remove single *.o files
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
答案1
得分: 0
只需在/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin
目录中创建一个clang-14
的符号链接,整个问题就解决了。
也许,如果将来有其他人遇到与我相同的问题,这是解决方案:
- 进入您的工具链的二进制目录(例如我的是
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin
)。 - 应该有一个名为
clang++
的文本文件。它只是一个包装文件,指向相同路径中的clang-14
编译器二进制文件,如果您查找的话。 - 将此文本文件重命名为其他名称,以免以后丢失它(我使用了
mv ./clang++ ./clang++1
)。 - 现在通过
ln -s ./clang-14 ./clang++
为您的编译器创建符号链接。 - 现在您可以从您的makefile中调用此符号链接,这是输出:
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -o ../bin/server_executable.out ../bin/Filesystem.o ../bin/Shell.o ../bin/Packet.o ../bin/Server.o ../bin/server_main.o
英文:
Answer:
The whole pain now is gone by simply making a symbolic link
of clang-14
inside /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin
directory.
Perhaps, if in future, someone else will face the same problem as me, here is the solution:
-
go to your toolchain's binary directory (e.g. mine is
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin
) -
there should be a text file called
clang++
. it is just a wrapper file pointing toclang-14
compiler binary fie which resides in the same path, if you look for it. -
rename this text file to something else just for not losing it later (I did
mv ./clang++ ./clang++1
) -
Now make a symbolic link for your compiler by
ln -s ./clang-14 ./clang++
. -
now you can call this symbolic link from your makefile and this is the output:
/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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 /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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 /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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 /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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 /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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 /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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 /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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 /usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/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/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7a-linux-androideabi33 --sysroot=/usr/android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/sysroot -o ../bin/server_executable.out ../bin/Filesystem.o ../bin/Shell.o ../bin/Packet.o ../bin/Server.o ../bin/server_main.o
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论