LLVM在Android NDK工具链中的用途是什么?

Nik*_*las 7 c++ linux android toolchain android-ndk

LLVM在Android NDK工具链中的用途是什么?


简要回顾一下:

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

以下内容摘自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的toolchains文件夹中的内容:

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
Run Code Online (Sandbox Code Playgroud)

这让我很困惑。我认为llvm是一种工具链,因为它位于此处,紧挨其他工具链。同样,Android NDK工具链中LLVM的实际用途是什么?

谢谢您的帮助 :)

mst*_*sjo 11

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(构建过程中使用的次要工具),而且每个体系结构也包含一个副本(甚至尽管从技术上讲,它们可能会在各种体系结构上运行)。

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


shi*_*hen 7

LLVM现在是一个umbrela项目,它包含多种模块化且可重用的编译器和工具链技术。您可以在LLVM编译器基础结构中查看更多详细信息。

对于Android NDK,从r13b开始,llvm成为默认工具链,从r18b起删除了gcc。

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

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

在此处输入图片说明

可能有用的参考:CMake构建工具链中“ strip”命令的Android NDK路径变量


更新

只是对不同的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 
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

在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 
Run Code Online (Sandbox Code Playgroud)

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

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

另外请注意,toolchains/llvm/prebuilt/darwin-x86_64包含所有的Android ABI的支持,即aarch64-linux-androidarm64-V8Aarm-linux-androideabiarmeabi-V7Ai686-linux-android86x86_64-linux-androidx86_64的

因此,如果您只想使用llvm工具链,则可以尝试NDK r19b。