zoukankan      html  css  js  c++  java
  • 使用NDK的Cmake编译报错:Invalid Android NDK revision

    使用NDK的Cmake编译报错:Invalid Android NDK revision

    在Windows上,下载Android的SDK之后,其自带有NDK,同时有CMake。当我们使用cmake.exe程序编译项目时,假如使用如下编译语句

    E:AndroidSdkcmake3.10.2.4988404incmake.exe -DCMAKE_TOOLCHAIN_FILE=E:AndroidSdkcmake3.10.2.4988404android.toolchain.cmake -DANDROID_ABI="arm64-v8a" -DANDROID_NDK=E:AndroidSdk
    dk-bundle -DCMAKE_GENERATOR="Ninja" -DCMAKE_MAKE_PROGRAM=E:AndroidSdkcmake3.10.2.4988404in
    inja.exe ./
    

    则其会报类似错误如下

    CMake Error at E:/Android/Sdk/cmake/3.10.2.4988404/android.toolchain.cmake:356 (message):
      Invalid Android NDK revision (should be 12): 19.2.5345600.
    Call Stack (most recent call first):
      E:/Android/Sdk/cmake/3.10.2.4988404/share/cmake-3.10/Modules/CMakeDetermineSystem.cmake:94 (include)
      CMakeLists.txt:30 (project)
    
    
    CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
    CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
    CMake Error: CMAKE_ASM_COMPILER not set, after EnableLanguage
    -- Configuring incomplete, errors occurred!
    

    我们顺着错误,打开E:/Android/Sdk/cmake/3.10.2.4988404/android.toolchain.cmake,定位到356行,代码如下

    string(REGEX REPLACE "${ANDROID_NDK_SOURCE_PROPERTIES_REGEX}" "\1"
    	ANDROID_NDK_PACKAGE_REVISION "${ANDROID_NDK_SOURCE_PROPERTIES}")
    if(NOT ANDROID_NDK_PACKAGE_REVISION MATCHES "^${ANDROID_NDK_REVISION}\.")
    	message(FATAL_ERROR "Invalid Android NDK revision (should be ${ANDROID_NDK_REVISION}): ${ANDROID_NDK_PACKAGE_REVISION}.")
    endif()
    

    显然,报错的原因是ANDROID_NDK_PACKAGE_REVISIONANDROID_NDK_REVISION不匹配,其分别为1912,其中前者为我们当前使用的NDK版本。而后者的12是怎么来的呢?我们在脚本搜索,发现其在脚本的开头就有设置

    cmake_minimum_required(VERSION 3.6.0)
    set(ANDROID_NDK_REVISION 12)
    

    这样,自然就不能匹配。那么原因是啥呢?估计是因为cmake是作为一个单独的模块在维护,而没有保持同步,因为CMake官方的版本已经到3.18了,而Android SDK中的才为3.10,它引入cmake这个版本的时候,估计刚好是对应的NDK 12,所以也就有这个限制。那么,是不是我们直接把set(ANDROID_NDK_REVISION 12)改为set(ANDROID_NDK_REVISION 19)就好了?我试了下,确实也是没问题的,可以顺利生成编译脚本build.ninja。但我们有更好的办法,来避免对源文件修改,以防未知错误。

    解决

    其实ndk-bundle目录下面就自带有android.toolchain.cmake文件,我们只需要这个文件就可以了

     E:AndroidSdkcmake3.10.2.4988404incmake.exe -DCMAKE_TOOLCHAIN_FILE=E:AndroidSdk
    dk-bundleuildcmakeandroid.toolchain.cmake -DANDROID_ABI="arm64-v8a" -DANDROID_NDK=E:AndroidSdk
    dk-bundle -DCMAKE_GENERATOR="Ninja" -DCMAKE_MAKE_PROGRAM=E:AndroidSdkcmake3.10.2.4988404in
    inja.exe -DANDROID_PLATFORM=android-23
    

    这样就可以顺利编译成功了。
    那为什么使用这个文件就可以了呢?其原因不是因为在这个里面有set(ANDROID_NDK_REVISION 19),而是它根本就没有对NDK版本进行检查,它直接从NDK文件中读取当前NDK版本,然后检测其是否合法而已。

    file(READ "${ANDROID_NDK}/source.properties" ANDROID_NDK_SOURCE_PROPERTIES)
    
    set(ANDROID_NDK_REVISION_REGEX
      "^Pkg\.Desc = Android NDK
    Pkg\.Revision = ([0-9]+)\.([0-9]+)\.([0-9]+)(-beta([0-9]+))?")
    if(NOT ANDROID_NDK_SOURCE_PROPERTIES MATCHES "${ANDROID_NDK_REVISION_REGEX}")
      message(SEND_ERROR "Failed to parse Android NDK revision: ${ANDROID_NDK}/source.properties.
    ${ANDROID_NDK_SOURCE_PROPERTIES}")
    endif()
    
  • 相关阅读:
    Tomcat性能调优方案
    内存泄露和内存溢出
    HashMap和Hashtable的区别
    properties类是Hashtable的子类
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/willhua/p/13195757.html
Copyright © 2011-2022 走看看