ผู้ผลิต

Android NDK รองรับการใช้ CMake เพื่อ คอมไพล์โค้ด C และ C++ สำหรับแอปพลิเคชันของคุณ หน้านี้กล่าวถึงวิธีใช้ CMake ด้วย NDK ผ่าน ExternalNativeBuild ของปลั๊กอิน Android Gradle หรือเมื่อ การเรียกใช้ CMake โดยตรง

ไฟล์ Toolchain ของ CMake

NDK รองรับ CMake ผ่านไฟล์เครื่องมือเชน ไฟล์ Toolchain คือไฟล์ CMake ที่ปรับแต่งลักษณะการทำงานของ Toolchain สำหรับการคอมไพล์แบบข้ามแพลตฟอร์ม Toolchain ไฟล์ที่ใช้สำหรับ NDK จะอยู่ใน NDK ที่ <NDK>/build/cmake/android.toolchain.cmake

พารามิเตอร์บิลด์ เช่น ABI, minSdkVersion ฯลฯ จะอยู่ในคำสั่ง เมื่อเรียกใช้ cmake ดูรายการอาร์กิวเมนต์ที่รองรับได้ที่ อาร์กิวเมนต์ Toolchain

"ใหม่" ไฟล์ Toolchain

ก่อนหน้านี้ NDK ได้ทดลองใช้ไฟล์ Toolchain ใหม่ซึ่ง จะลดความแตกต่างด้านลักษณะการทำงานระหว่างการใช้ไฟล์ Toolchain ของ NDK และ โดยใช้การสนับสนุน CMake ในตัว ซึ่งก็ต้องใช้ความพยายามอย่างมาก งาน (ซึ่งยังไม่เสร็จสมบูรณ์) แต่ไม่ได้ปรับปรุงการทำงานจริง เราจึงจะไม่จัดการกับเรื่องนี้อีกต่อไป

"ใหม่" ไฟล์ Toolchain มีการถดถอยของลักษณะการทำงานเมื่อเทียบกับ "เดิม" Toolchain ลักษณะการทำงานเริ่มต้นคือเวิร์กโฟลว์ที่แนะนำ หากคุณ โดยใช้ -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF เราขอแนะนำให้นำธงออก จากบิลด์ของคุณ ไฟล์ Toolchain ใหม่ไม่เคยเทียบเท่ากับไฟล์เดิม Toolchain จึงมีโอกาสเกิดการถดถอยของพฤติกรรม

แม้ว่าเราจะไม่แนะนำให้ใช้ไฟล์ Toolchain ใหม่ แต่ขณะนี้ยังไม่มี วางแผนที่จะนำออกจาก NDK เนื่องจากจะทำให้บิลด์ที่ใช้องค์ประกอบ ความแตกต่างด้านลักษณะการทำงานระหว่างไฟล์ Toolchain ใหม่และไฟล์เดิม และ น่าเสียดายที่เราต้องเปลี่ยนชื่อตัวเลือกใหม่ เพื่อให้เห็นอย่างชัดเจนว่า "เวอร์ชันเดิม" จริงๆ แล้ว ที่แนะนำให้ใช้เป็นการรบกวนผู้ใช้ของตัวเลือกนี้ด้วย หากคุณพอใจกับการใช้ ไฟล์ Toolchain ใหม่ ที่คุณไม่จำเป็นต้องย้ายข้อมูล แต่โปรดทราบว่าข้อบกพร่องที่ส่ง กับลักษณะการทำงานของไฟล์ Toolchain ใหม่ อาจจะไม่ได้รับการแก้ไข และ ที่คุณต้องย้ายข้อมูล

การใช้งาน

เกรเดิล

การใช้ไฟล์ Toolchain ของ CMake เป็นไปโดยอัตโนมัติเมื่อใช้ externalNativeBuild ดูเพิ่มโค้ด C และ C++ ลงใน ของโปรเจ็กต์เพื่อดูข้อมูลเพิ่มเติม

บรรทัดคำสั่ง

เมื่อสร้างด้วย CMake นอก Gradle ไฟล์ Toolchain นั้นเองและ ต้องส่งอาร์กิวเมนต์ไปยัง CMake เช่น

$ cmake \
    -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=$ABI \
    -DANDROID_PLATFORM=android-$MINSDKVERSION \
    $OTHER_ARGS

อาร์กิวเมนต์ Toolchain

ระบบส่งอาร์กิวเมนต์ต่อไปนี้ไปยังไฟล์เครื่องมือเชน CMake ได้ หากกำลังสร้าง ด้วย Gradle ให้เพิ่มอาร์กิวเมนต์ลงใน android.defaultConfig.externalNativeBuild.cmake.arguments ตามที่อธิบายไว้ใน ExternalNativeBuild เอกสาร หากกำลังสร้างจากบรรทัดคำสั่ง ให้ส่งอาร์กิวเมนต์ไปที่ CMake ด้วย -D เช่น บังคับให้ armeabi-v7a ไม่สร้างด้วย Neon สนับสนุน โดยให้ผ่าน -DANDROID_ARM_NEON=FALSE

ANDROID_ABI

ABI เป้าหมาย ดูข้อมูลเกี่ยวกับ ABI ที่รองรับได้ที่ ABI ของ Android

เกรเดิล

Gradle ระบุอาร์กิวเมนต์นี้โดยอัตโนมัติ ไม่ต้องตั้งค่านี้อย่างชัดแจ้ง ในไฟล์ build.gradle หากต้องการควบคุมสิ่งที่ ABI Gradle กำหนดเป้าหมาย ใช้ abiFilters ตามที่อธิบายไว้ใน Android ABI

บรรทัดคำสั่ง

CMake บิลด์สําหรับเป้าหมายเดียวต่อบิลด์ หากต้องการกำหนดเป้าหมายเป็น Android มากกว่า 1 เครื่อง ABI คุณต้องสร้าง 1 ครั้งต่อ ABI ขอแนะนำให้ใช้บิลด์อื่น ไดเรกทอรีสำหรับ ABI แต่ละรายการเพื่อหลีกเลี่ยงการขัดแย้งระหว่างบิลด์

ค่า หมายเหตุ
armeabi-v7a
armeabi-v7a with NEON ราคาเท่ากันกับ armeabi-v7a
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

ระบุว่าจะสร้างคำสั่งสำหรับแขนหรือนิ้วโป้งสำหรับ armeabi-v7a ไม่มี สำหรับ ABI อื่นๆ ดูข้อมูลเพิ่มเติมได้ที่ ABI ของ Android เอกสารประกอบ

ค่า หมายเหตุ
แขน
นิ้วโป้ง ลักษณะการทำงานเริ่มต้น

ANDROID_NATIVE_API_LEVEL

ชื่อแทนของ ANDROID_PLATFORM

ANDROID_PLATFORM

ระบุระดับ API ขั้นต่ำที่แอปพลิเคชันหรือไลบรารีรองรับ ช่วงเวลานี้ ตรงกับminSdkVersionของแอปพลิเคชัน

เกรเดิล

เมื่อใช้ปลั๊กอิน Android Gradle ค่านี้จะถูกตั้งเป็นโดยอัตโนมัติ ตรงกับ minSdkVersion ของแอปพลิเคชัน และไม่ควรตั้งค่าด้วยตนเอง

บรรทัดคำสั่ง

เมื่อเรียกใช้ CMake โดยตรง ค่านี้จะเริ่มต้นเป็นระดับ API ต่ำสุด รองรับการใช้งาน NDK เช่น ใช้ NDK r20 เป็นค่าเริ่มต้น เป็น API ระดับ 16

พารามิเตอร์นี้ยอมรับรูปแบบหลายรูปแบบ

  • android-$API_LEVEL
  • $API_LEVEL
  • android-$API_LETTER

รูปแบบ $API_LETTER ช่วยให้คุณระบุ android-N ได้โดยไม่ต้อง ให้ระบุหมายเลขที่เชื่อมโยงกับรุ่นนั้นๆ โปรดทราบว่าบางรุ่น ได้รับการเพิ่ม API โดยไม่ได้เพิ่มตัวอักษร สามารถระบุ API เหล่านี้ได้ โดยใส่คำต่อท้าย -MR1 ต่อท้าย ตัวอย่างเช่น API ระดับ 25 คือ android-N-MR1

ANDROID_STL

ระบุ STL ที่จะใช้สำหรับแอปพลิเคชันนี้ สำหรับข้อมูลเพิ่มเติม โปรดดูที่ C++ การสนับสนุนห้องสมุด ระบบจะใช้ c++_static โดยค่าเริ่มต้น

ค่า หมายเหตุ
c++_ แชร์ ตัวแปรไลบรารีที่ใช้ร่วมกันของ libc++
c++_static ตัวแปรไลบรารีแบบคงที่ของ libc++
ไม่มี ไม่รองรับไลบรารีมาตรฐาน C++
ระบบ STL ของระบบ

ทำความเข้าใจคำสั่งบิลด์ CMake

เมื่อแก้ไขข้อบกพร่องของบิลด์ CMake ควรทราบบิลด์ที่เฉพาะเจาะจง อาร์กิวเมนต์ที่ Gradle ใช้เมื่อการคอมไพล์แบบข้ามระบบสำหรับ Android

ปลั๊กอิน Android Gradle บันทึกอาร์กิวเมนต์ของบิลด์ที่ใช้สำหรับเรียกใช้ บิลด์ CMake สำหรับ ABI แต่ละรายการและประเภทบิลด์ จับคู่กับ build_command.txt ไฟล์เหล่านี้อยู่ในรายการต่อไปนี้ ไดเรกทอรี:

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

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างของอาร์กิวเมนต์ CMake เพื่อสร้าง รุ่นที่สามารถแก้ไขข้อบกพร่องได้ของตัวอย่าง hello-jni ซึ่งกำหนดเป้าหมายไปยัง 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

ใช้ไลบรารีที่สร้างไว้ล่วงหน้า

หากไลบรารีที่สร้างไว้ล่วงหน้าที่คุณต้องการนำเข้ามีการเผยแพร่เป็น AAR ให้ทำตาม เอกสารทรัพยากร Dependency ของ Studio เพื่อนำเข้าและนำไปใช้ หากไม่ได้ใช้ AGP คุณสามารถติดตามได้ https://google.github.io/prefab/example-workflow.html แต่มีโอกาสมาก ย้ายข้อมูลไปยัง AGP ได้ง่ายขึ้น

สำหรับไลบรารีที่ไม่ได้กระจายเป็น AAR คำแนะนำเกี่ยวกับการใช้ที่สร้างไว้ล่วงหน้า ไลบรารีที่มี CMake โปรดดูเอกสารประกอบ add_library เกี่ยวกับ IMPORTED เป้าหมายในคู่มือ CMaker

การสร้างโค้ดของบุคคลที่สาม

การสร้างโค้ดของบุคคลที่สามใน CMake ทำได้หลายวิธี โครงการ และตัวเลือกที่มีประสิทธิภาพที่สุดจะขึ้นอยู่กับสถานการณ์ของคุณ ดีที่สุด มักจะไม่ทำเช่นนี้เลย แต่ให้สร้าง AAR สำหรับฟังก์ชัน และใช้ไลบรารีนั้นในแอปพลิเคชันของคุณได้ คุณไม่จำเป็นต้อง เผยแพร่ว่า AAR โดยอาจเป็นโปรเจ็กต์ภายในโปรเจ็กต์ Gradle ของคุณ

หากไม่ได้เลือก ให้ทำดังนี้

  • ผู้จำหน่าย (คัดลอก) แหล่งที่มาของบุคคลที่สามไปยังที่เก็บของคุณและการใช้งาน add_subdirectory เพื่อสร้างได้ วิธีนี้จะใช้ได้เฉพาะเมื่อไลบรารีอื่น ที่สร้างด้วย CMake
  • กำหนดโปรเจ็กต์ภายนอก
  • สร้างไลบรารีแยกจากโปรเจ็กต์แล้วทำตาม ใช้ไลบรารีที่สร้างไว้ล่วงหน้าเพื่อนำเข้าเป็นไลบรารีที่สร้างไว้ล่วงหน้า

การรองรับ YASM ใน CMake

NDK ให้การสนับสนุน CMake สำหรับรหัสประกอบอาคารที่เขียนด้วย YASM เพื่อเรียกใช้บน x86 และ x86-64 สถาปัตยกรรม YASM เป็นโปรแกรมประกอบแบบโอเพนซอร์สสำหรับ x86 และ x86-64 จากโมเดลประกอบของ NASM

หากต้องการสร้างโค้ดแอสเซมบลีด้วย CMake ให้ทำการเปลี่ยนแปลงต่อไปนี้ใน CMakeLists.txt:

  1. เรียกใช้ enable_language โดยกำหนดค่าเป็น ASM_NASM
  2. ขึ้นอยู่กับว่าคุณกำลังสร้างไลบรารีที่ใช้ร่วมกันหรือไฟล์ปฏิบัติการ ไบนารี ให้เรียกใช้ add_library หรือ add_executable ใน ส่งอาร์กิวเมนต์ในรายการไฟล์ต้นฉบับที่ประกอบด้วยไฟล์ .asm ไฟล์ สำหรับโปรแกรมการประกอบใน YASM และไฟล์ .c สำหรับ C ที่เกี่ยวข้อง ไลบรารีหรือฟังก์ชัน

ตัวอย่างต่อไปนี้แสดงวิธีการกำหนดค่า CMakeLists.txt ให้ สร้างโปรแกรม YASM เป็นไลบรารีที่ใช้ร่วมกัน

cmake_minimum_required(VERSION 3.6.0)

enable_language(ASM_NASM)

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

สำหรับตัวอย่างของวิธีสร้างโปรแกรม YASM เป็นไฟล์ปฏิบัติการ โปรดดู yasm ทดสอบ ในที่เก็บ Git ของ NDK

รายงานปัญหา

หากพบปัญหาเกี่ยวกับไฟล์ NDK หรือไฟล์เครื่องมือ CMake โปรดรายงาน ผ่านเครื่องมือติดตามปัญหา android-ndk/ndk บน GitHub สำหรับ Gradle หรือ ปัญหาเกี่ยวกับปลั๊กอิน Android Gradle โปรดรายงานข้อบกพร่องของ Studio แทน