CMake

Dengan Android Studio 2.2 dan yang lebih tinggi, Anda bisa menggunakan NDK dan CMake untuk menyusun kode C dan C++ menjadi pustaka asli. Android Studio lalu mengemas pustaka Anda ke dalam APK menggunakan Gradle, sistem pembangunan terintegrasi IDE.

Jika Anda baru menggunakan CMake bersama Android Studio, buka Menambahkan Kode C dan C++ ke Proyek Anda untuk mempelajari dasar-dasar menambahkan sumber asli ke proyek, membuat skrip pembangunan CMake, dan menambahkan proyek CMake sebagai dependensi Gradle. Halaman ini menyediakan beberapa informasi tambahan yang bisa Anda gunakan untuk menyesuaikan pembangunan CMake.

Menggunakan variable CMake dalam Gradle

Setelah Anda menautkan Gradle ke proyek CMake, Anda bisa mengonfigurasi variable khusus NDK yang bisa mengubah cara CMake membangun pustaka asli. Untuk meneruskan argumen ke CMake dari file level modul build.gradle, gunakan DSL berikut:

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake build script.
    externalNativeBuild {
      cmake {
        ...
        // Use the following syntax when passing arguments to variables:
        // arguments "-DVAR_NAME=ARGUMENT".
        arguments "-DANDROID_ARM_NEON=TRUE",
        // If you're passing multiple arguments to a variable, pass them together:
        // arguments "-DVAR_NAME=ARG_1 ARG_2"
        // The following line passes 'rtti' and 'exceptions' to 'ANDROID_CPP_FEATURES'.
                  "-DANDROID_CPP_FEATURES=rtti exceptions"
      }
    }
  }
  buildTypes {...}

  // Use this block to link Gradle to your CMake build script.
  externalNativeBuild {
    cmake {...}
  }
}

Tabel berikut menjelaskan beberapa variabel yang dapat Anda konfigurasikan saat menggunakan CMake dengan NDK.

Nama variabel Argumen Keterangan
ANDROID_PLATFORM

Untuk daftar lengkap nama platform dan citra sistem Android yang sesuai, lihat Android NDK Native API.

Menentukan nama platform Android target. Misalnya, android-18 menentukan Android 4.3 (API level 18).

Daripada mengubah bendera ini langsung, Anda harus menyetel properti minSdkVersion dalam defaultConfig atau blok productFlavors di file level modul build.gradle. Hal ini memastikan pustaka hanya digunakan oleh aplikasi yang diinstal di perangkat yang menjalankan versi Android yang memadai. Rantai alat CMake lalu memilih versi platform terbaik untuk ABI yang Anda bangun dengan logika berikut:

  1. Jika ada versi platform untuk ABI yang setara dengan minSdkVersion, CMake akan menggunakan versi itu.
  2. Jika tidak, jika terdapat versi platform lebih rendah daripada minSdkVersion untuk ABI, CMake akan menggunakan platform versi tertinggi. Ada alasan masuk akal karena versi platform yang hilang biasanya berarti tidak ada perubahan pada API platform asli sejak versi yang tersedia sebelumnya.
  3. Jika tidak, CMake menggunakan versi platform yang tersedia berikutnya lebih tinggi daripada minSdkVersion.
ANDROID_STL

Untuk daftar lengkap pilihan, lihat Waktu Proses Bantuan

Secara default, CMake menggunakan c++_static.

Menentukan yang harus digunakan STL CMake.

ANDROID_PIE
  • ON (default bila ANDROID_PLATFORM = android-16 dan lebih tinggi)
  • OFF (default bila ANDROID_PLATFORM = android-15 dan lebih rendah)

Menentukan eksekutabel bergantung posisi (PIE). Penaut dinamis Android mendukung PIE di Android 4.1 (API level 16) dan lebih tinggi.

ANDROID_CPP_FEATURES

Variabel ini kosong secara default. Namun, berikut ini adalah beberapa contoh argumen yang bisa Anda lewati:

  • rtti (menunjukkan bahwa kode Anda menggunakan RTTI)
  • exceptions (menunjukkan bahwa kode menggunakan pengecualian C++)

Menentukan fitur C++ tertentu yang perlu digunakan CMake saat mengompilasi pustaka asli, seperti pengecualian RTTI (RunTime Type Information) dan C++.

ANDROID_ALLOW_UNDEFINED_SYMBOLS
  • TRUE
  • FALSE (default)

Menentukan apakah melontarkan kesalahan simbol yang tidak didefinisikan jika CMake menemukan referensi yang tidak didefinisikan saat membangun pustaka asli. Untuk menonaktifkan tipe kesalahan ini, setel variabel ini ke TRUE.

ANDROID_ARM_MODE
  • arm
  • thumb (default)

Menentukan apakah menghasilkan biner target ARM dalam mode arm atau thumb. Dalam mode thumb, masing-masing petunjuk selebar 16 bit dan ditautkan dengan pustaka STL di direktori thumb/. Menguraikan arm meminta CMake untuk menghasilkan file benda pustaka dalam mode arm 32-bit.

ANDROID_ARM_NEON
  • TRUE
  • FALSE

Menentukan apakah CMake harus membangun pustaka asli dengan dukungan NEON. Dikembalikan ke true untuk API level 23 atau versi lebih baru, jika tidak false.

ANDROID_DISABLE_FORMAT_STRING_CHECKS
  • TRUE
  • FALSE (default)

Menentukan apakah mengumpulkan kode sumber dengan perlindungan string format. Saat aktif, pengompilasi melontarkan kesalahan jika string format tidak konstan digunakan dalam fungsi bergaya printf.

Memahami perintah build CMake

Saat men-debug masalah pembangunan CMake, akan bermanfaat jika mengetahui argumen pembangunan yang digunakan Android Studio saat mengompilasi silang Android.

Android Studio menyimpan argumen pembangunan yang digunakan untuk menjalankan pembangunan CMake, dalam file cmake_build_command.txt. Untuk setiap Application Binary Interface (ABI) yang ditargetkan aplikasi Anda, dan setiap tipe pembangunan untuk ABI itu (yaitu, rilis atau debug), Android Studio menghasilkan salinan file cmake_build_command.txt untuk konfigurasi tertentu itu. Android Studio kemudian menggantikan file yang dihasilkan di direktori berikut:

<project-root>/<module-root>/.externalNativeBuild/cmake/<build-type>/<ABI>/

Tips: Di Android Studio, Anda bisa cepat melihat file ini menggunakan pintasan keyboard penelusuran (shift+shift) dan memasukkan cmake_build_command.txt dalam kolom input.

Cuplikan berikut memperlihatkan contoh argumen CMake untuk membangun rilis yang dapat di-debug dari hello-jni contoh yang menargetkan arsitektur armeabi-v7a.

Executable : /usr/local/google/home/{$USER}/Android/Sdk/cmake/3.6.3155560/bin/cmake
arguments :
-H/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/src/main/cpp
-B/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/.externalNativeBuild/cmake/arm7Debug/armeabi-v7a
-GAndroid Gradle - Ninja
-DANDROID_ABI=armeabi-v7a
-DANDROID_NDK=/usr/local/google/home/{$USER}/Android/Sdk/ndk-bundle
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/usr/local/google/home/{$USER}/Dev/github-projects/googlesamples/android-ndk/hello-jni/app/build/intermediates/cmake/arm7/debug/obj/armeabi-v7a
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_MAKE_PROGRAM=/usr/local/google/home/{$USER}/Android/Sdk/cmake/3.6.3155560/bin/ninja
-DCMAKE_TOOLCHAIN_FILE=/usr/local/google/home/{$USER}/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-DANDROID_NATIVE_API_LEVEL=23
-DANDROID_TOOLCHAIN=clang
jvmArgs : 

Argumen pembangunan

Tabel berikut menyoroti argumen pembangunan CMake utama untuk Android. Argumen pembangunan ini tidak dimaksudkan untuk ditetapkan oleh pengembang. Sebagai gantinya, Android Plugin untuk Gradle menyetel argumen ini berdasarkan konfigurasi build.gradle dalam proyek Anda.

Argumen Pembangunan Keterangan
-G <build-system>

Tipe file pembangunan yang dihasilkan CMake.

Untuk proyek dalam Android Studio dengan kode asli, <build-system> disetel ke Android Gradle - Ninja. Setelan ini menunjukkan bahwa CMake menggunakan sistem pembangunan ninja untuk mengompilasikan dan menghubungkan sumber C/C++ untuk aplikasi Anda. CMake juga menghasilkan file android_gradle_build.json yang berisi metadata untuk plugin Gradle tentang pembangunan CMake seperti bendera pengompilasi dan nama target.

Setelan ini menunjukkan bahwa CMake menggunakan Gradle bersama dengan sistem pembangunan ninja untuk mengompilasi dan menghubungkan sumber C/C++ untuk aplikasi Anda. Sistem pembangunan ninja satu-satunya penghasil yang didukung Studio.

-DANDROID_ABI <abi>

ABI target.

NDK mendukung serangkaian ABI, yang dijelaskan dalam Manajemen ABI. Pilihan sama seperti variabel APP_ABI yang digunakan alat ndk-build.

Secara default, Gradle membangun pustaka asli Anda ke dalam file .so terpisah untuk ABI yang didukung NDK, kemudian mengemas semuanya ke dalam APK. Jika Anda ingin Gradle membangun hanya untuk konfigurasi ABI, ikuti petunjuk dalam Menambahkan Kode C dan C++ ke Proyek Anda.

Jika ABI target tidak ditetapkan, CMake dikembalikan ke default menggunakan armeabi-v7a.

Nama target valid adalah:

  • armeabi: CPU berbasis ARMv5TE dengan operasi titik mengapung perangkat lunak.
  • armeabi-v7a: Perangkat berbasis ARMv7 dengan petunjuk FPU perangkat keras (VFPv3_D16).
  • armeabi-v7a with NEON: Sama seperti armeabi-v7a, tetapi mengaktifkan petunjuk titik mengapung NEON. Proses ini setara dengan -DANDROID_ABI=armeabi-v7a dan -DANDROID_ARM_NEON=ON.
  • arm64-v8a: Rangkaian petunjuk ARMv8 AArch64.
  • x86: Rangkaian petunjuk IA-32.
  • x86_64 - Rangkaian petunjuk untuk arsitektur x86-64.
-DANDROID_NDK <path> Jalur absolut ke direktori akar dari penginstalan NDK di host Anda.
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY <path> Lokasi di host tempat CMake menaruh file target LIBRARY saat dibangun.
-DCMAKE_BUILD_TYPE <type> Sama seperti tipe pembangunan untuk alat ndk-build. Nilai yang valid adalah Release dan Debug. Untuk menyederhanakan proses debug, CMake tidak menghilangkan rilis atau versi debug sebagai bagian dari pembangunan. Namun, Gradle menghilangkan biner saat sistem ini mengemasnya ke dalam APK.
-DCMAKE_MAKE_PROGRAM <program-name> Alat untuk meluncurkan sistem pembangunan asli. Plugin Gradle menetapkan nilai ini ke penghasil CMake ninja yang dikemas dengan Android SDK.
-DCMAKE_TOOLCHAIN_FILE <path> Jalur ke file android.toolchain.cmake yang digunakan CMake untuk kompilasi silang Android. Biasanya, file ini terletak di direktori $NDK/build/cmake/, tempat $NDK adalah direktori penginstalan NDK di host. Untuk informasi lebih lanjut tentang file rantai alat, lihat Kompilasi Lintas Android.
-DANDROID_NATIVE_API_LEVEL <level> Level Android API yang dikompilasi CMake.
-DANDROID_TOOLCHAIN <type> Rantai alat pengompilasi yang digunakan CMake. Kembalikan ke default clang

Dukungan YASM di CMake

NDK memberikan dukungan CMake untuk membangun code assembly yang tertulis dalam YASM untuk dijalankan di arsitektur x86 dan x86-64. YASM adalah assembler sumber terbuka untuk arsitektur x86 dan x86-64, berdasarkan assembler NASM.

Akan bermanfaat jika Anda menautkan program atau rutinitas bahasa assembly dengan kode C untuk mengakses perpustakaan atau fungsi C dari kode assembly. Anda juga bisa menyertakan rutinitas assembly singkat dalam kode C yang dikomplikasi untuk memanfaatkan kinerja mesin yang lebih baik yang dihasilkan kode assembly.

Untuk membangun kode assembly dengan CMake, lakukan perubahan berikut dalam CMakeLists.txt proyek:

  1. Panggil enable_language dengan nilai yang disetel ke ASM_NASM.
  2. Tergantung apakah Anda membangun pustaka bersama atau biner eksekutabel, panggil add_library atau add_executable. Dalam argumen, masukkan daftar file sumber yang terdiri dari file .asm untuk program assembly dalam YASM dan file .c untuk pustaka atau fungsi C terkait.

Cuplikan berikut memperlihatkan cara mengonfigurasi CMakeLists.txt untuk membangun program YASM sebagai pustaka bersama.

cmake_minimum_required(VERSION 3.6.0)

enable_language(ASM_NASM)

add_library(test-yasm SHARED jni/test-yasm.c jni/print_hello.asm)

Misalnya cara membangun program YASM sebagai eksekutabel, lihat kode yasm dalam repositori git NDK.

Melaporkan masalah

Jika Anda mengalami masalah yang bukan terjadi karena versi sumber terbuka CMake, laporkan melalui pelacak masalah android-ndk/ndk di GitHub.