กำหนดค่า CMake

สคริปต์บิลด์ CMake เป็นไฟล์ข้อความธรรมดาที่คุณต้องตั้งชื่อ CMakeLists.txt และรวมคำสั่งที่ CMake ใช้เพื่อสร้าง C/C++ ของไลบรารี หากแหล่งที่มาดั้งเดิมของคุณยังไม่มีบิลด์ CMake คุณต้องสร้างบัญชีด้วยตัวเอง และใส่ CMake ที่เหมาะสม คำสั่ง หากต้องการดูวิธีติดตั้ง CMake โปรดดูติดตั้งและกำหนดค่า NDK และ CMake

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

หลังจากกำหนดค่าสคริปต์บิลด์ CMake ใหม่แล้ว คุณต้องทำดังนี้ กำหนดค่า Gradle เพื่อรวมโปรเจ็กต์ CMake เป็นทรัพยากร Dependency ของบิลด์เพื่อให้ Gradle สร้าง สร้างแพ็กเกจไลบรารีเนทีฟด้วย APK ของแอป

หมายเหตุ: หากโปรเจ็กต์ใช้ ndk-build คุณไม่จำเป็นต้องทำดังนี้ สร้างสคริปต์บิลด์ CMake คุณเพียงแค่ กำหนดค่า Gradle ให้รวมโครงการไลบรารีเนทีฟที่มีอยู่ด้วย โดยกำหนดเส้นทางไปยัง Android.mk

สร้างสคริปต์บิลด์ CMake

ในการสร้างไฟล์ข้อความธรรมดาที่คุณใช้เป็นสคริปต์บิลด์ CMake ได้ โดยทำตามขั้นตอนต่อไปนี้

  1. เปิดแผงโครงการจากด้านซ้ายของ IDE และเลือก มุมมองโปรเจ็กต์จากเมนูแบบเลื่อนลง
  2. คลิกขวาที่ไดเรกทอรีรากของ your-module และ เลือก New > ไฟล์

    หมายเหตุ: คุณสร้างสคริปต์บิลด์ในตำแหน่งใดก็ได้ที่ต้องการ อย่างไรก็ตาม เมื่อกำหนดค่าสคริปต์บิลด์ เส้นทางไปยังแหล่งที่มาดั้งเดิม ไฟล์และไลบรารีสัมพันธ์กับตำแหน่งของสคริปต์บิลด์

  3. ป้อน "CMakeLists.txt" เป็นชื่อไฟล์ แล้วคลิกตกลง

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

# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.

cmake_minimum_required(VERSION 3.4.1)

# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add_library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

เคล็ดลับ: คล้ายกับที่คุณบอกให้ CMake สร้างไลบรารีเนทีฟจาก คุณสามารถใช้ add_executable() เพื่อบอก CMake แทนสร้างคำสั่ง ที่ดำเนินการได้จากไฟล์ต้นฉบับเหล่านั้น อย่างไรก็ตาม การสร้างไฟล์ปฏิบัติการจาก แหล่งที่มาแบบเนทีฟเป็นตัวเลือก และการสร้างไลบรารีเนทีฟเพื่อรวมกลุ่มไว้ใน APK เป็นไปตามข้อกำหนดของโปรเจ็กต์ส่วนใหญ่

เมื่อคุณเพิ่มไฟล์ต้นฉบับหรือไลบรารีลงในสคริปต์บิลด์ของ CMake โดยใช้ add_library(), Android Studio แสดงไฟล์ส่วนหัวที่เกี่ยวข้องด้วย ในมุมมองโปรเจ็กต์หลังจากที่คุณซิงค์โปรเจ็กต์ อย่างไรก็ตาม ใน เพื่อให้ CMake ค้นหาไฟล์ส่วนหัวในระหว่างคอมไพล์ เพิ่มคำสั่ง include_directories() ใน CMake สคริปต์บิลด์และระบุเส้นทางไปยังส่วนหัวของคุณ:

add_library(...)

# Specifies a path to native header files.
include_directories(src/main/cpp/include/)

แบบแผน CMake ใช้เพื่อตั้งชื่อไฟล์ไลบรารีของคุณดังนี้

liblibrary-name.so

ตัวอย่างเช่น หากคุณระบุ "native-lib" เป็นชื่อไลบรารีที่ใช้ร่วมกันของคุณ ในสคริปต์บิลด์ CMake สร้างไฟล์ชื่อ libnative-lib.so อย่างไรก็ตาม เมื่อโหลดไลบรารีนี้ใน โค้ด Java หรือ Kotlin ใช้ชื่อที่คุณระบุในสคริปต์บิลด์ CMake ดังนี้

Kotlin

companion object {
    init {
        System.loadLibrary("native-lib");
    }
}

Java

static {
    System.loadLibrary("native-lib");
}

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

Android Studio จะเพิ่มไฟล์ต้นฉบับและส่วนหัวลงในไฟล์ กลุ่ม cpp ในแผงโปรเจ็กต์ โดยการใช้ คำสั่ง add_library() หลายรายการ คุณสามารถกำหนดคำสั่งเพิ่มเติม ไลบรารีสำหรับ CMake เพื่อสร้างจากไฟล์ต้นฉบับอื่นๆ

เพิ่ม API ของ NDK

Android NDK มีชุด API และไลบรารีแบบเนทีฟที่คุณอาจพบ มีประโยชน์ คุณสามารถใช้ API เหล่านี้โดยรวมไลบรารี NDK ใน CMakeLists.txt ไฟล์สคริปต์

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

เพิ่มคำสั่ง find_library() ในบิลด์ CMake เพื่อค้นหาไลบรารี NDK และจัดเก็บเส้นทางเป็นตัวแปร คุณใช้ ตัวแปรนี้เพื่อใช้อ้างอิงไลบรารี NDK ในส่วนอื่นๆ ของสคริปต์การสร้าง ตัวอย่างต่อไปนี้ระบุไลบรารีการสนับสนุนบันทึกเฉพาะของ Android และจัดเก็บเส้นทางใน log-lib:

find_library( # Defines the name of the path variable that stores the
              # location of the NDK library.
              log-lib

              # Specifies the name of the NDK library that
              # CMake needs to locate.
              log )

เพื่อให้ไลบรารีเนทีฟเรียกใช้ฟังก์ชันใน log คุณต้องลิงก์ไลบรารีโดยใช้คำสั่ง target_link_libraries() ใน สคริปต์บิลด์ CMake ของคุณ

find_library(...)

# Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the log library to the target library.
                       ${log-lib} )

NDK ยังมีไลบรารีบางส่วนเป็นซอร์สโค้ดที่คุณต้องสร้าง และลิงก์ไปยังไลบรารีเนทีฟ คุณสามารถคอมไพล์ซอร์สโค้ดเป็น ไลบรารีแบบเนทีฟโดยใช้คำสั่ง add_library() ใน CMake สคริปต์บิลด์ หากต้องการระบุเส้นทางไปยังคลัง NDK ท้องถิ่น คุณสามารถใช้ ตัวแปรเส้นทาง ANDROID_NDK ที่ Android Studio โดยอัตโนมัติ ที่กำหนดให้คุณ

คำสั่งต่อไปนี้จะบอก CMake เพื่อสร้าง android_native_app_glue.c ซึ่งจัดการ NativeActivity เหตุการณ์ในวงจรและการป้อนข้อมูลด้วยการสัมผัส ลงในไลบรารีแบบคงที่ แล้วลิงก์กับ native-lib:

add_library( app-glue
             STATIC
             ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )

# You need to link static libraries against your shared native library.
target_link_libraries( native-lib app-glue ${log-lib} )

เพิ่มไลบรารีที่สร้างไว้ล่วงหน้าอื่นๆ

การเพิ่มไลบรารีที่สร้างไว้ล่วงหน้าคล้ายกับการระบุไลบรารีเนทีฟอีกรายการสำหรับ CMake เพื่อสร้าง แต่เนื่องจากมีการสร้างไลบรารีไว้แล้ว คุณต้อง ใช้ Flag IMPORTED เพื่อบอก CMake ว่าคุณ ต้องการนำเข้าไลบรารีไปยังโปรเจ็กต์ของคุณเท่านั้น:

add_library( imported-lib
             SHARED
             IMPORTED )

จากนั้นคุณต้องระบุเส้นทางไปยังไลบรารีโดยใช้ set_target_properties() เป็น ดังที่แสดงด้านล่าง

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

add_library(...)
set_target_properties( # Specifies the target library.
                       imported-lib

                       # Specifies the parameter you want to define.
                       PROPERTIES IMPORTED_LOCATION

                       # Provides the path to the library you want to import.
                       imported-lib/src/${ANDROID_ABI}/libimported-lib.so )

หากต้องการให้ CMake ค้นหาไฟล์ส่วนหัวในระหว่างเวลาคอมไพล์ คุณต้องใช้ คำสั่ง include_directories() และระบุเส้นทางไปยัง ไฟล์ส่วนหัว:

include_directories( imported-lib/include/ )

หมายเหตุ: หากคุณต้องการสร้างแพ็กเกจไลบรารีที่สร้างไว้ล่วงหน้าซึ่งไม่ ทรัพยากร Dependency ของเวลาบิลด์ เช่น เมื่อเพิ่มไลบรารีที่สร้างไว้ล่วงหน้าซึ่งเป็น ของ imported-lib คุณไม่จำเป็นต้องดำเนินการ ทำตามวิธีการเพื่อลิงก์ไลบรารี

หากต้องการลิงก์ไลบรารีที่สร้างไว้ล่วงหน้ากับไลบรารีเนทีฟของคุณเอง ให้เพิ่มไลบรารีดังกล่าวลงใน คำสั่ง target_link_libraries() ในสคริปต์บิลด์ CMake

target_link_libraries( native-lib imported-lib app-glue ${log-lib} )

ในการรวมไลบรารีที่สร้างไว้ล่วงหน้าลงใน APK ของคุณ คุณต้องทำดังนี้ กำหนดค่า Gradle ด้วยตนเองโดยใช้บล็อก sourceSets เพื่อ รวมเส้นทางไปยังไฟล์ .so ของคุณ หลังจากสร้าง APK คุณสามารถ สามารถตรวจสอบแพ็กเกจไลบรารี Gradle ใน APK ของคุณได้โดยใช้ ตัววิเคราะห์ APK

รวมโปรเจ็กต์ CMake อื่นๆ

หากต้องการสร้างโปรเจ็กต์ CMake หลายโปรเจ็กต์และรวมเอาต์พุตไว้ใน คุณสามารถใช้ไฟล์ CMakeLists.txt 1 ไฟล์เป็น สคริปต์บิลด์ CMake ระดับบนสุด (ซึ่งเป็นสคริปต์ที่คุณ ลิงก์ ไปยัง Gradle) และเพิ่มโปรเจ็กต์ CMake เพิ่มเติมเป็นทรัพยากร Dependency ของบิลด์นั้น สคริปต์ สคริปต์บิลด์ CMake ระดับบนสุดต่อไปนี้ใช้ add_subdirectory() ที่จะระบุ อีกไฟล์ CMakeLists.txt เป็นทรัพยากร Dependency ของบิลด์แล้วจึงลิงก์ โดยเทียบกับเอาต์พุตเช่นเดียวกับไลบรารีอื่นๆ ที่สร้างไว้ล่วงหน้า

# Sets lib_src_DIR to the path of the target CMake project.
set( lib_src_DIR ../gmath )

# Sets lib_build_DIR to the path of the desired output directory.
set( lib_build_DIR ../gmath/outputs )
file(MAKE_DIRECTORY ${lib_build_DIR})

# Adds the CMakeLists.txt file located in the specified directory
# as a build dependency.
add_subdirectory( # Specifies the directory of the CMakeLists.txt file.
                  ${lib_src_DIR}

                  # Specifies the directory for the build outputs.
                  ${lib_build_DIR} )

# Adds the output of the additional CMake build as a prebuilt static
# library and names it lib_gmath.
add_library( lib_gmath STATIC IMPORTED )
set_target_properties( lib_gmath PROPERTIES IMPORTED_LOCATION
                       ${lib_build_DIR}/${ANDROID_ABI}/lib_gmath.a )
include_directories( ${lib_src_DIR}/include )

# Links the top-level CMake build output against lib_gmath.
target_link_libraries( native-lib ... lib_gmath )

เรียก CMake จากบรรทัดคำสั่ง

ใช้คำสั่งต่อไปนี้เพื่อเรียก CMake เพื่อสร้างโปรเจ็กต์นินจาภายนอก ของ Android Studio

cmake
-Hpath/to/cmakelists/folder
-Bpath/to/generated/ninja/project/debug/ABI
-DANDROID_ABI=ABI                               // For example, arm64-v8a
-DANDROID_PLATFORM=platform-version-string      // For example, android-16
-DANDROID_NDK=android-sdk/ndk/ndk-version
-DCMAKE_TOOLCHAIN_FILE=android-sdk/ndk/ndk-version/build/cmake/android.toolchain.cmake
-G Ninja

คำสั่งนี้จะสร้างโปรเจ็กต์นินจาที่สามารถเรียกใช้เพื่อสร้าง ไลบรารีไฟล์ปฏิบัติการของ Android (.so ไฟล์) CMAKE_TOOLCHAIN_FILE คือ ที่จำเป็นต่อการใช้การสนับสนุน CMake ของ NDK สำหรับ CMake 3.21 ขึ้นไปมี CMake ในตัว สามารถใช้การรองรับ NDK แทนได้ แต่ต้องใช้ตัวแปรกลุ่มอื่น ตามที่อธิบายไว้ในเอกสารประกอบการคอมไพล์ข้ามอุปกรณ์สำหรับ Android ของ CMake