使用NDK的Cmake編譯報錯:Invalid Android NDK revision


使用NDK的Cmake編譯報錯:Invalid Android NDK revision

在Windows上,下載Android的SDK之后,其自帶有NDK,同時有CMake。當我們使用cmake.exe程序編譯項目時,假如使用如下編譯語句

E:\Android\Sdk\cmake\3.10.2.4988404\bin\cmake.exe -DCMAKE_TOOLCHAIN_FILE=E:\Android\Sdk\cmake\3.10.2.4988404\android.toolchain.cmake -DANDROID_ABI="arm64-v8a" -DANDROID_NDK=E:\Android\Sdk\ndk-bundle\ -DCMAKE_GENERATOR="Ninja" -DCMAKE_MAKE_PROGRAM=E:\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.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:\Android\Sdk\cmake\3.10.2.4988404\bin\cmake.exe -DCMAKE_TOOLCHAIN_FILE=E:\Android\Sdk\ndk-bundle\build\cmake\android.toolchain.cmake -DANDROID_ABI="arm64-v8a" -DANDROID_NDK=E:\Android\Sdk\ndk-bundle\ -DCMAKE_GENERATOR="Ninja" -DCMAKE_MAKE_PROGRAM=E:\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.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\nPkg\\.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.\n${ANDROID_NDK_SOURCE_PROPERTIES}")
endif()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM