NDK及其作用
NDK(Native Development Kit)是一個由 Google 提供的工具集,用於在 Android 平臺上開發 C++ 或其他本機程式碼。NDK 的主要作用是允許開發人員使用 C、C++ 和其他本機語言編寫程式碼,並將其編譯為能夠在 Android 裝置上執行的本機程式碼(通常是共享庫 .so 檔案)。
NDK 的主要作用:
-
本機程式碼開發:NDK 允許開發人員使用 C、C++ 或其他本機語言編寫 Android 應用的部分或全部程式碼。這對於需要高效能運算、直接訪問硬體功能或跨平臺相容性的應用程式非常有用。
-
效能最佳化:透過使用本機程式碼,開發人員可以更好地最佳化應用程式的效能,特別是對於需要執行計算密集型任務或需要更高控制權的應用程式。
-
複用現有程式碼:NDK 允許開發人員將現有的 C、C++ 程式碼或庫整合到 Android 應用中,這樣可以更好地複用現有的程式碼資產。
-
訪問底層硬體:透過本機程式碼,開發人員可以更容易地訪問裝置的底層硬體功能,如相機、感測器等,以及執行更高階別的硬體控制。
-
跨平臺相容性:使用 NDK,開發人員可以更輕鬆地將現有的跨平臺 C、C++ 程式碼移植到 Android 平臺,從而實現跨平臺相容性。
-
加密和安全性:透過將關鍵部分的程式碼編譯為本機程式碼,可以提高應用程式的安全性,因為本機程式碼更難被逆向工程或篡改。
NDK下載
NDK下載方式有兩種:
- 透過官網連結下載對應作業系統的NDK
- 筆者另一篇博文(AndroidSDK下載(不透過AndroidStudio))提到的透過命令列工具進行下載
下載後目錄結構大致如下:
├─build
│ ├─cmake
│ │ └─hooks
│ │ ├─post
│ │ └─pre
│ ├─core
│ │ └─toolchains
│ │ ├─aarch64-linux-android-clang
│ │ ├─arm-linux-androideabi-clang
│ │ ├─riscv64-linux-android-clang
│ │ ├─x86-clang
│ │ └─x86_64-clang
│ ├─gmsl
│ └─tools
├─meta
├─prebuilt
│ └─windows-x86_64
├─python-packages
├─shader-tools
│ └─windows-x86_64
├─simpleperf
├─sources
├─toolchains
│ └─llvm
│ └─prebuilt
│ └─windows-x86_64
└─wrap.sh
交叉編譯示例
示例一
opencv編譯
- 下載opencv原始碼
- 在包含
CMakeLists.txt
的根目錄中新建編譯目錄build - 開啟build目錄
- 執行cmake命令如下:
cmake -G"Ninja"
-DCMAKE_ANDROID_NDK="xxx/android-ndk"
-DCMAKE_MAKE_PROGRAM="xxx/ninja.exe"
-DCMAKE_TOOLCHAIN_FILE="xxx/android-ndk/build/cmake/android.toolchain.cmake" -DCMAKE_INSTALL_PREFIX="../install"
-DCMAKE_SYSTEM_NAME="Android"
-DANDROID_NATIVE_API_LEVEL="25"
-DANDROID_PLATFORM="android-25"
-DCMAKE_ANDROID_ARCH_ABI="arm64-v8a"
-DCMAKE_ANDROID_STL_TYPE="c++_shared"
-DBUILD_ANDROID_PROJECTS=OFF .. - 其中關鍵的配置
CMAKE_ANDROID_NDK
用於配置ndk所在目錄,CMAKE_TOOLCHAIN_FILE
用於配置工具鏈檔案,此檔案包含了編譯過程中所需的工具、庫、及平臺選項。CMAKE_SYSTEM_NAME
告訴cmake編譯的作業系統為android,ANDROID_PLATFORM
用於指定與Android SDK匹配的版本,ANDROID_NATIVE_API_LEVEL
指定 NDK版本的API級別,CMAKE_ANDROID_ARCH_ABI
用於指定cpu架構, 最後-G用於指定構建系統, 由於筆者是在Windows 上編譯, 所以指定了Ninja, Linux一般指定為Unix Makefiles
- 由於筆者選擇的構建系統為
Ninja
, 所以呼叫Ninja
開始編譯, 最後透過呼叫Ninja install
進行安裝。 與make類似
重要的編譯選項為
ANDROID_PLATFORM
及CMAKE_ANDROID_ARCH_ABI
、CMAKE_TOOLCHAIN_FILE
。可根據不同的作業系統選擇不同的構建系統, 如Linux一般為
Unix Makefiles
, Windows一般為Ninja
或Visual Studio
示例二
結合vscode編譯一個自己寫的so庫
程式碼的部分就省略了, 主要看關鍵配置CMakePresets.json檔案:
{
"version": 8,
"configurePresets": [
{
"name": "android compile",
"displayName": "android compile",
"description": "Sets Ninja generator, build and install directory",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_ANDROID_NDK": "xxx/android-ndk",
"CMAKE_MAKE_PROGRAM": "xxx/ninja.exe",
"ANDROID_ABI": "arm64-v8a",
"ANDROID_PLATFORM": "android-21",
"CMAKE_ANDROID_STL_TYPE":"c++_shared",
"CMAKE_TOOLCHAIN_FILE": "xxx/build/cmake/android.toolchain.cmake",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
}
}
]
}
然後編輯自己的CMakeLists.txt
檔案, 與本機編譯(對應交叉編譯)沒什麼不同。
透過CMakePresets.json達到了示例一相同的效果, 只是方式不一樣。 編譯選項都是一樣的。