[关闭]
@ltlovezh 2020-04-01T17:59:28.000000Z 字数 2284 阅读 1675

NDK Cmake

NDK Cmake


CMake与NDK搭配使用时,可以配置的部分变量:
1. ANDROID_PLATFORM:指定Android的目标版本,对应$NDK/platforms/目录下的版本。通常情况下是defaultConfig中的minSdkVersion,这样就能确保所有大于等于minSdkVersion的设备都可以使用编译生成的库。 但是也有例外,比如:当ANDROID_ABI=arm64-v8a时,即使minSdkVersion18,但是ANDROID_PLATFORM=android-21,因为从API21开始才支持64位库。这里的版本直接决定了使用$NDK/platforms目录下哪个系统版本的库和头文件。
2. ANDROID_STL:指定使用的STL库,STL库不是Android系统自带的,若使用静态库(c++_static),则会链接进目标库;若使用动态库(c++_shared),Gradle会将动态库(libc++_shared.so)和目标库一起打包。详情可参考C++ 库支持
3. ANDROID_ARM_NEON:指定CMake是否构建支持NEON的目标库。API大于等于23时,默认值为true,否则为false。

Cmake编译时,是通过$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin下的交叉编译工具进行编译和链接,arm-linux-androideabi-4.9表示对应abi架构和位数,例如:arm64就是aarch64-linux-android-4.9
而链接时所依赖的系统库,则是在$NDK/platforms/${ANDROID_PLATFORM}/${abi}/usr/lib目录下。

用于Android CMake的关键构建参数。这些构建参数并非由开发者设置。相反,Android Plugin for Gradle会根据您项目的build.gradle配置,设置这些参数。
1. ANDROID_NDK:NDK的绝对目录,根据local.properties中的ndk.dir属性去设置。

上述-D的变量,都可以在CMakeLists.txt中直接访问,例如:${ANDROID_NDK}

NDK库

Ndk包含3部分内容:

  1. 系统so文件(主要是platforms目录下),链接时可以保证链接通过,但是不会跟目标so一起打包,因为系统本身就包含这些so,动态链接。例如: android-ndk-r16b/platforms/android-17/arch-arm/usr/lib/libEGL.so
  2. 源码,其中源码以两种方式呈现:1.标准库的.a文件(sources/cxx-stl); 2. c源码(sources/android、 sources/third_party),这些都会打包进so文件。
  3. C++ stl库,提供了.a和.so两种形式,可以在gradle中通过ANDROID_STL指定使用静态库还是动态库,使用动态库的话,动态库so会一起打包到library中。

一个Android Library,添加NDK的支持,仅需要在模块级build.gradle添加相关配置,然后剩下的事情就交给Cmake了,至于NDK的代码位置理论上可以在任何位置。

一个Android Library 包含的so文件由两部分组成,一个是该Library指定的CmakeList文件生成的so文件,另外一个是通过jniLibs.srcDirs
指定的目录中的so库文件。

cpufeatures

cpufeatures模块位于$ANDROID_NDK/sources/android/cpufeatures目录下,可以用于判断设备的CPU信息,可参考cpufeatures

  1. /* A list of valid values returned by android_getCpuFamily().
  2. * They describe the CPU Architecture of the current process.
  3. */
  4. typedef enum {
  5. ANDROID_CPU_FAMILY_UNKNOWN = 0,
  6. ANDROID_CPU_FAMILY_ARM,
  7. ANDROID_CPU_FAMILY_X86,
  8. ANDROID_CPU_FAMILY_MIPS,
  9. ANDROID_CPU_FAMILY_ARM64,
  10. ANDROID_CPU_FAMILY_X86_64,
  11. ANDROID_CPU_FAMILY_MIPS64,
  12. ANDROID_CPU_FAMILY_MAX /* do not remove */
  13. } AndroidCpuFamily;
  14. /* Return the CPU family of the current process.
  15. * 对于64位系统上的32位程序,此函数返回32位架构
  16. */
  17. extern AndroidCpuFamily android_getCpuFamily(void);
  18. /* Return the number of CPU cores detected on this device.
  19. * 可能高于实际在线的核心数
  20. */
  21. extern int android_getCpuCount(void);
  22. /*
  23. * 返回一组位标记,每个标记代表一个CPU系列特定的功能,需要结合android_getCpuFamily的返回值来判断这些位标记,即不同的CPU架构,这里的位标记表示不同含义。
  24. */
  25. extern uint64_t android_getCpuFeatures(void);
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注