Android NDK hỗ trợ sử dụng CMake để biên dịch mã C và C ++ cho ứng dụng của bạn. Trang này thảo luận về cách sử dụng CMake bằng NDK thông qua ExternalNativeBuild
của Trình bổ trợ Android cho Gradle hoặc khi gọi trực tiếp CMake.
Tệp chuỗi công cụ CMake
NDK hỗ trợ CMake thông qua một tệp chuỗi công cụ. Tệp chuỗi công cụ là các tệp CMake tuỳ chỉnh hành vi của chuỗi công cụ để biên dịch chéo. Tệp chuỗi công cụ dành cho NDK nằm trong NDK tại <NDK>/build/cmake/android.toolchain.cmake
.
Các tham số bản dựng như ABI, minSdkVersion
, v.v. được cung cấp trên dòng lệnh khi gọi cmake
. Để biết danh sách các đối số được hỗ trợ, hãy xem phần Các đối số chuỗi công cụ.
Cách sử dụng
Gradle
Tệp chuỗi công cụ CMake tự động được sử dụng trong trường hợp dùng externalNativeBuild
. Xem hướng dẫn Thêm mã C và C++ của vào dự án của Android Studio để biết thêm thông tin.
Dòng lệnh
Khi tạo bằng CMake bên ngoài Gradle, chính tệp chuỗi công cụ và đối số của tệp phải được truyền đến CMake. Ví dụ:
$ cmake \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$ABI \
-DANDROID_PLATFORM=android-$MINSDKVERSION \
$OTHER_ARGS
Đối số chuỗi công cụ
Bạn có thể truyền các đối số sau đến tệp chuỗi công cụ CMake. Nếu tạo bằng Gradle, hãy thêm các đối số vào android.defaultConfig.externalNativeBuild.cmake.arguments
như mô tả trong tài liệu ExternalNativeBuild. Nếu tạo từ dòng lệnh, hãy truyền các đối số đến CMake bằng -D
. Ví dụ: Để buộc armeabi-v7a luôn tạo bằng tính năng hỗ trợ Neon, hãy truyền -DANDROID_ARM_NEON=TRUE
.
ANDROID_ABI
ABI (Giao diện nhị phân ứng dụng) mục tiêu. Để biết thông tin về các ABI (Giao diện nhị phân ứng dụng) được hỗ trợ, hãy xem ABI Android.
Gradle
Gradle sẽ tự động cung cấp đối số này. Không đặt đối số này một cách rõ ràng trong tệp build.gradle
. Để kiểm soát loại ABI mà Gradle nhắm mục tiêu đến, hãy sử dụng abiFilters
như mô tả trong ABI Android.
Dòng lệnh
CMake xây dựng cho một mục tiêu duy nhất/bản dựng. Để nhắm mục tiêu đến nhiều ABI Android, bạn phải tạo một bản dựng cho mỗi ABI. Bạn nên sử dụng nhiều thư mục bản dựng khác nhau cho từng ABI để tránh xung đột giữa các bản dựng.
Giá trị | Ghi chú |
---|---|
armeabi-v7a |
|
armeabi-v7a with NEON |
Tương tự như -DANDROID_ABI=armeabi-v7a -DANDROID_ARM_NEON=ON |
arm64-v8a |
|
x86 |
|
x86_64 |
ANDROID_ARM_MODE
Chỉ định xem có tạo hướng dẫn về ARM hoặc Thumb cho armeabi-v7a hay không. Không có hiệu lực đối với các ABI khác. Để biết thêm thông tin, hãy xem tài liệu về ABI Android.
Giá trị | Ghi chú |
---|---|
arm | |
thumb | Hành động mặc định. |
ANDROID_ARM_NEON
Bật hoặc tắt NEON cho armeabi-v7a. Không ảnh hưởng đến các ABI khác. Giá trị mặc định là đúng cho API (minSdkVersion
hoặc ANDROID_PLATFORM
) cấp 23 trở lên, nếu không là sai. Để biết thêm thông tin, hãy xem tài liệu Hỗ trợ Neon.
Giá trị | Ghi chú |
---|---|
TRUE | Chế độ mặc định cho API cấp 23 trở lên. |
FALSE | Chế độ mặc định cho API cấp 22 trở về trước. |
ANDROID_LD
Chọn trình liên kết muốn sử dụng. lld hiện đang được thử nghiệm cho NDK và có thể được bật với đối số này.
Giá trị | Ghi chú |
---|---|
lld | Bật lld. |
mặc định | Dùng trình liên kết mặc định cho ABI đã cho. |
ANDROID_NATIVE_API_LEVEL
Bí danh cho ANDROID_PLATFORM.
ANDROID_PLATFORM
Chỉ định cấp độ API tối thiểu mà ứng dụng hoặc thư viện hỗ trợ. Giá trị này tương ứng với minSdkVersion
của ứng dụng.
Gradle
Khi sử dụng Trình bổ trợ Android cho Gradle, giá trị này sẽ tự động được đặt cho khớp với minSdkVersion
của ứng dụng và không được đặt theo cách thủ công.
Dòng lệnh
Khi gọi trực tiếp CMake, giá trị này sẽ mặc định áp dụng cho API cấp thấp nhất mà NDK bạn sử dụng hỗ trợ. Ví dụ: Với NDK r20, giá trị này mặc định áp dụng cho API cấp 16.
Hệ thống chấp nhận nhiều định dạng cho tham số này:
android-$API_LEVEL
$API_LEVEL
android-$API_LETTER
Định dạng $API_LETTER
cho phép bạn chỉ định android-N
mà không cần xác định số liên kết với bản phát hành đó. Xin lưu ý rằng một số bản phát hành đã tăng cấp độ API nhưng không tăng chữ cái. Bạn có thể chỉ định các API này bằng cách thêm hậu tố -MR1
. Ví dụ: API cấp 25 là android-N-MR1
.
ANDROID_STL
Chỉ định STL bạn muốn sử dụng cho ứng dụng này. Để biết thêm thông tin, hãy xem phần Hỗ trợ thư viện C++. Theo mặc định, c++_static
sẽ được sử dụng.
Giá trị | Ghi chú |
---|---|
c++_shared | Biến thể thư viện dùng chung của libc++. |
c++_static | Biến thể thư viện tĩnh của libc++. |
không có | Không hỗ trợ thư viện chuẩn C++. |
hệ thống | STL hệ thống |
Tìm hiểu về lệnh bản dựng CMake
Khi gỡ lỗi các vấn đề về bản dựng CMake, bạn nên biết các đối số bản dựng cụ thể mà Gradle sử dụng khi biên dịch chéo cho Android.
Trình bổ trợ Android cho Gradle sẽ lưu các đối số bản dựng mà công cụ này sử dụng để thực thi bản dựng CMake dành cho mỗi cặp ABI và loại hình xây dựng vào build_command.txt
. Các tệp này có trong thư mục sau:
<project-root>/<module-root>/.cxx/cmake/<build-type>/<ABI>/
Đoạn mã sau đây cho thấy ví dụ về các đối số CMake để tạo một bản phát hành có thể gỡ lỗi của mẫu hello-jni
nhắm mục tiêu đến cấu trúc armeabi-v7a
.
Executable : ${HOME}/Android/Sdk/cmake/3.10.2.4988404/bin/cmake
arguments :
-H${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/src/main/cpp
-DCMAKE_FIND_ROOT_PATH=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/.cxx/cmake/universalDebug/prefab/armeabi-v7a/prefab
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_TOOLCHAIN_FILE=${HOME}/Android/Sdk/ndk/22.1.7171670/build/cmake/android.toolchain.cmake
-DANDROID_ABI=armeabi-v7a
-DANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
-DANDROID_PLATFORM=android-23
-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a
-DCMAKE_ANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
-DCMAKE_MAKE_PROGRAM=${HOME}/Android/Sdk/cmake/3.10.2.4988404/bin/ninja
-DCMAKE_SYSTEM_NAME=Android
-DCMAKE_SYSTEM_VERSION=23
-B${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/.cxx/cmake/universalDebug/armeabi-v7a
-GNinja
jvmArgs :
Build command args: []
Version: 1
Sử dụng thư viện tạo sẵn
Nếu thư viện tạo sẵn mà bạn cần nhập được phân phối dưới dạng AAR (đề xuất được tự động áp dụng), hãy làm theo tài liệu về phần phụ thuộc của Studio để nhập và sử dụng những thư viện đó. Nếu không dùng AGP, bạn có thể làm theo hướng dẫn trên https://google.github.io/prefab/example-workflow.html nhưng rất có thể việc di chuyển sang AGP sẽ dễ dàng hơn rất nhiều.
Đối với các thư viện không được phân phối dưới dạng AAR, để được hướng dẫn về cách sử dụng thư viện tạo sẵn bằng CMake, hãy xem tài liệu add_library
về các mục tiêu IMPORTED
trong hướng dẫn sử dụng CMake.
Tạo mã bên thứ ba
Có một số cách để tạo mã bên thứ ba trong dự án CMake và cách nào hiệu quả nhất sẽ tuỳ thuộc vào tình huống của bạn. Thông thường, cách tốt nhất là hoàn toàn không làm việc này. Thay vào đó, hãy tạo AAR cho thư viện rồi dùng đề xuất đó trong ứng dụng. Bạn không nhất thiết phải phát hành AAR đó. Bạn có thể dùng riêng AAR đó trong dự án Gradle của mình.
Nếu cách này không phù hợp:
- Nhà cung cấp (tức là sao chép) nguồn bên thứ ba vào kho lưu trữ của bạn và dùng add_subdirectory để tạo kho lưu trữ đó. Cách này chỉ hiệu quả nếu thư viện khác cũng được tạo bằng CMake.
- Xác định ExternalProject.
- Tạo thư viện riêng biệt với dự án của bạn và làm theo hướng dẫn Sử dụng thư viện tạo sẵn để nhập thư viện đó làm thư viện tạo sẵn.
Hỗ trợ YASM trong CMake
NDK hỗ trợ dùng CMake để tạo mã tập hợp được ghi trong YASM nhằm chạy trên cấu trúc x86 và x86-64. YASM là một trình tập hợp nguồn mở cho các cấu trúc x86 và x86-64, dựa trên trình tập hợp NASM.
Để tạo mã tập hợp bằng CMake, hãy thực hiện các thay đổi sau trong CMakeLists.txt
của dự án:
- Gọi
enable_language
với giá trị được đặt thànhASM_NASM
. - Tuỳ thuộc vào việc bạn đang tạo thư viện dùng chung hay tệp nhị phân có thể thực thi, hãy gọi
add_library
hoặcadd_executable
. Trong các đối số, hãy truyền một danh sách các tệp nguồn chứa các tệp.asm
cho chương trình tập hợp trong YASM và tệp.c
cho các hàm hoặc thư viện C liên kết.
Đoạn mã sau đây cho biết cách bạn có thể định cấu hình CMakeLists.txt
để tạo chương trình YASM dưới dạng thư viện dùng chung.
cmake_minimum_required(VERSION 3.6.0)
enable_language(ASM_NASM)
add_library(test-yasm SHARED jni/test-yasm.c jni/print_hello.asm)
Để biết ví dụ về cách tạo chương trình YASM dưới dạng tệp thực thi, hãy xem kiểm thử yasm trong kho lưu trữ git NDK.
Báo cáo sự cố
Nếu bạn gặp bất kỳ sự cố nào với NDK hoặc tệp chuỗi công cụ CMake, hãy báo cáo thông qua công cụ theo dõi lỗi android-ndk/ndk trên GitHub. Đối với các sự cố về Gradle hoặc Trình bổ trợ Android cho Gradle, hãy báo cáo lỗi Studio.