在Android NDK工具链中使用LLVM有什么用?

问题描述 投票:2回答:2

在Android NDK工具链中使用LLVM有什么用?


一点回顾:

我在Ubuntu上使用Gradlew构建我的本机项目,目标是arm和x86_64架构。似乎LLVM被用来调用arm-linux-androideabi-4.9的c / C ++编译器以及x86_64(?)

以下内容摘自armeabi-v7a / ndkBuild_build_output.log:

/ home / mypc / Android / android-ndk-r17c / toolchains / llvm / prebuilt / linux-x86_64 / bin / clang ++ -MMD -MP -MF / home / mypc / git / android-project-1 / build / intermediates / ndkBuild /debug/obj/local/armeabi-v7a/objs-debug/module-5/stream_cpp.od-gcc- toolchain /home/mypc/Android/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt / linux-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument ...

..以下是从x86_64 / ndkBuild_build_output.log中提取的:

/ home / mypc / Android / android-ndk-r17c / toolchains / llvm / prebuilt / linux-x86_64 / bin / clang ++ -MMD -MP -MF / home / mypc / git / android-project-1 / build / intermediates / ndkBuild /debug/obj/local/x86_64/objs-debug/module-5/stream_cpp.od-gcc- toolchain /home/mypc/Android/android-ndk-r17c/toolchains/x86_64-4.9/prebuilt/linux-x86_64 -target x86_64-none-linux-android -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC -Wno-invalid-command-line-argument ...

  • “......”表示这个单行命令的长尾我已经被删除了。
  • 个人文件夹和项目的名称已更改。

让我们来看看Android NDK的工具链文件夹中的内容:

myacc:~/.../android-ndk-r17c/toolchains$ tree -L 1
.
├── aarch64-linux-android-4.9
├── arm-linux-androideabi-4.9
├── llvm
├── mips64el-linux-android-4.9
├── mipsel-linux-android-4.9
├── NOTICE-MIPS
├── NOTICE-MIPS64
├── renderscript
├── x86-4.9
└── x86_64-4.9

这让我很困惑。我认为llvm是一种工具链,因为它放在这里,旁边是其他工具链。再次,在Android NDK工具链中实际使用LLVM是什么?

谢谢您的帮助 :)

android c++ linux android-ndk toolchain
2个回答
10
投票

LLVM是编译器(后端)。使用的编译器是Clang,它位于llvm目录中。 (LLVM是Clang组件的名称,用于执行实际的代码生成,即后端。)

以前,NDK使用GCC作为编译器。使用GCC,每个目标体系结构(arm,aarch64,x86等)都有一个单独的GCC副本,该副本是使用配置的单个目标构建的。另一方面,Clang / LLVM可以使用单个编译器可执行文件来定位任何已配置的体系结构。因此,使用Clang,您将节省一些磁盘空间,避免使用许多单独的编译器可执行文件。这就是为什么llvm目录树只有一个副本。

在NDK r17中,您可以使用GCC和Clang编译器;默认情况下使用Clang,但GCC仍可用于尚未能使用Clang迁移的项目。在较新的NDK版本中,旧的GCC被删除。

在较新的NDK版本中,即使删除了GCC,仍然会保留像aarch64-linux-android-4.9这样的体系结构特定目录,因为仍然使用GNU binutils(构建过程使用的小工具),并且每个体系结构也有一个副本(即使它们在技术上可能跨架构工作)。

至于为何建造例如手臂也提到了x86_64;当您运行Clang或GCC时,您正在为运行x86_64的构建计算机运行可执行文件,因此prebuilt/linux-x86_64是路径的一部分。


5
投票

LLVM现在是一个umbrela项目,它包含多个模块化和可重用的编译器和工具链技术。您可以在The LLVM Compiler Infrastructure查看更多详情。

对于Android NDK,llvm成为默认工具链,因为r13b和gcc自r18b后被删除。

根据工具链目录toolchains/llvm/prebuilt/darwin-x86_64,llvm支持所有ABI,即x86,x86_64,arm,arm64。

可能在将来的NDK版本中,llvm目录下只有一个toolchains目录,当所有gcc相关工具,头文件和库完全移植到llvm时。

enter image description here

可能有所帮助的参考文献:Android NDK path variable for "strip" command in CMake build tool chain


Updates

刚刚对不同的NDK版本进行了快速测试,以检查用于交叉编译的--gcc-toolchain--sysroot的配置。

在r16b

--target=armv7-none-linux-androideabi 
--gcc-toolchain=~/ndks/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
--sysroot=~/ndks/android-ndk-r16b/sysroot 

在r17c

--target=armv7-none-linux-androideabi
--gcc-toolchain=~/ndks/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
--sysroot=~/ndks/android-ndk-r17c/sysroot

在r18b

--target=armv7-none-linux-androideabi19
--gcc-toolchain=~/ndks/android-ndk-r18b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
--sysroot=~/ndks/android-ndk-r18b/sysroot

在r19b

--target=armv7-none-linux-androideabi19 
--gcc-toolchain=~/ndks/android-ndk-r19b/toolchains/llvm/prebuilt/darwin-x86_64 
--sysroot=~/ndks/android-ndk-r19b/toolchains/llvm/prebuilt/darwin-x86_64/sysroot 

如上所示,在NDK r19b之前,NDK使用clang编译器,但--gcc-toolchain--sysroot被配置为构建工具,头文件和库的旧路径。

但是,由于NDK r19b,--gcc-toolchain--sysroot被配置为新的工具链llvm,即toolchains/llvm/prebuilt/darwin-x86_64,并且将使用工具(例如,ranlib,ar,strip等)头文件和“llvm版本”的库。

此外,请注意toolchains/llvm/prebuilt/darwin-x86_64包含对所有Android ABI的支持,即arm64-v8a的aarch64-linux-android,armeabi-v7a的arm-linux-androideabi,x86的i686-linux-android,x86_64的x86_64-linux-android

因此,如果您想纯粹使用llvm工具链,可以试用NDK r19b。

© www.soinside.com 2019 - 2024. All rights reserved.