Konfigurowanie CMake

Skrypt kompilacji CMake to zwykły plik tekstowy, który należy nazwać CMakeLists.txt i zawiera polecenia używane przez CMake do tworzenia Biblioteki C/C++. Jeśli źródła natywne nie mają jeszcze kompilacji CMake musisz utworzyć własny skrypt i dodać do niego odpowiednią poleceń. Aby dowiedzieć się, jak zainstalować CMake, zobacz Instalowanie i konfigurowanie pakietu NDK i CMake.

W tej sekcji opisano kilka podstawowych poleceń, które należy uwzględnić w kompilacji skrypt, aby wskazać CMake, których źródeł użyć przy tworzeniu bibliotece. Więcej informacji znajdziesz w oficjalnej dokumentacji polecenia CMake.

Po skonfigurowaniu nowego skryptu kompilacji CMake musisz wykonać konfigurowanie Gradle uwzględnić projekt CMake jako zależność kompilacji, dzięki czemu Gradle kompiluje umieszcza w pakiecie Twoją bibliotekę natywną w pakiecie APK aplikacji.

Uwaga: jeśli Twój projekt używa polecenia ndk-build, nie musisz i utworzyć skrypt kompilacji w CMake. Wystarczy skonfiguruj Gradle , aby uwzględnić istniejący projekt biblioteki natywnej, podając ścieżkę do pliku Android.mk.

Tworzenie skryptu kompilacji CMake

Aby utworzyć zwykły plik tekstowy, którego można użyć jako skryptu kompilacji CMake, wykonaj następujące czynności:

  1. Otwórz panel Projekt po lewej stronie IDE i wybierz Widok Projekt.
  2. Kliknij prawym przyciskiem myszy katalog główny your-module, a następnie wybierz Nowy > Plik.

    Uwaga: skrypt kompilacji możesz utworzyć w dowolnej lokalizacji. Jednak podczas konfigurowania skryptu kompilacji ścieżki do źródła natywnego zależą od lokalizacji skryptu kompilacji.

  3. Wpisz „CMakeLists.txt” i kliknij OK.

Teraz możesz skonfigurować skrypt kompilacji, dodając polecenia CMake. Aby przekazać instrukcje Aby utworzyć bibliotekę natywną na podstawie natywnego kodu źródłowego, dodaj polecenia cmake_minimum_required() i add_library() do skryptu kompilacji:

# 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 )

Wskazówka: podobnie jak w przypadku polecenia CMake, aby utworzyć bibliotekę natywną plików źródłowych, możesz użyć parametru add_executable(), aby nakazać CMake zamiast tego utworzenie z tych plików źródłowych. Jednak tworzenie plików wykonywalnych z źródła natywne są opcjonalne, a tworzenie bibliotek natywnych do spakowania w pakiet Plik APK spełnia większość wymagań dotyczących projektu.

Gdy dodasz plik źródłowy lub bibliotekę do skryptu kompilacji CMake za pomocą add_library(), Android Studio pokazuje też powiązane pliki nagłówka w widoku Projekt po zsynchronizowaniu projektu. Jednak w przypadku tak aby CMake zlokalizowała pliki nagłówkowe w czasie kompilacji, musisz dodanie polecenia include_directories() do obiektu CMake, skrypt kompilacji i podaj ścieżkę do nagłówków:

add_library(...)

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

Zgodnie z konwencją, według której CMake używa nazwy pliku biblioteki, jest taka:

liblibrary-name.so

Jeśli na przykład wpiszesz „native-lib”, jako nazwę biblioteki udostępnionej. w skrypcie kompilacji CMake tworzy plik o nazwie libnative-lib.so Jednak podczas wczytywania tej biblioteki w W kodzie Java lub Kotlin użyj nazwy podanej w skrypcie kompilacji CMake:

Kotlin

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

Java

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

Uwaga: jeśli zmienisz nazwę biblioteki lub usuniesz ją w kompilacji CMake skryptu, musisz wyczyścić projekt, zanim Gradle wprowadzi zmiany lub powoduje usunięcie starszej wersji biblioteki z pakietu APK. Aby wyczyścić projektu, wybierz Kompilacja > Wyczyść projekt na pasku menu.

Android Studio automatycznie dodaje pliki źródłowe i nagłówki do grupę cpp w panelu Projekt. Za pomocą wielu poleceń add_library(), możesz zdefiniować dodatkowe do tworzenia bibliotek na podstawie innych plików źródłowych.

Dodaj interfejsy API NDK

Android NDK zawiera zestaw natywnych interfejsów API i bibliotek, które możesz znaleźć przydatne. Możesz użyć dowolnego z tych interfejsów API, dodając biblioteki NDK w pliku manifestu projektu CMakeLists.txt.

Gotowe biblioteki NDK już istnieją na platformie Androida, więc musisz je kompilować lub spakować do pliku APK. Ponieważ biblioteki NDK są już uwzględnione w ścieżce wyszukiwania CMake, nie musisz nawet określać w lokalizacji biblioteki w lokalnej instalacji NDK – wystarczy wpisz w CMake nazwę biblioteki, której chcesz używać, i połącz ją w porównaniu z własną biblioteką natywną.

Dodaj polecenie find_library() do kompilacji CMake skrypt do zlokalizowania biblioteki NDK i zapisania jej ścieżki jako zmiennej. Używasz tę zmienną, aby odwoływać się do biblioteki NDK w innych częściach skryptu kompilacji. Ten przykład zawiera bibliotekę obsługi dzienników dotyczących Androida i zapisuje swoją ścieżkę w 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 )

Aby biblioteka natywna mogła wywoływać funkcje w interfejsie log biblioteki, musisz połączyć biblioteki za pomocą polecenia target_link_libraries() skrypt kompilacji 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 zawiera też pewne biblioteki jako kod źródłowy, który jest wymagany i podaj link do biblioteki natywnej. Kod źródłowy możesz skompilować do postaci biblioteka natywna za pomocą polecenia add_library() w CMake skrypt kompilacji. Aby podać ścieżkę do lokalnej biblioteki NDK, możesz użyć zmiennej ścieżki ANDROID_NDK, która jest automatycznie konfigurowana w Android Studio. za Ciebie.

Poniższe polecenie informuje narzędzie CMake o konieczności skompilowania android_native_app_glue.c zarządza firmą NativeActivity oraz zdarzenia cyklu życia i dotykowe wprowadzanie danych do biblioteki statycznej. 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} )

Dodaj inne gotowe biblioteki

Dodawanie gotowej biblioteki przypomina określanie innej biblioteki natywnej Dbaj o siebie. Ponieważ biblioteka jest już utworzona, musisz użyj flagi IMPORTED, aby poinformować CMake, że chcą zaimportować bibliotekę do swojego projektu:

add_library( imported-lib
             SHARED
             IMPORTED )

Następnie podaj ścieżkę do biblioteki za pomocą set_target_properties() jako poniżej.

Niektóre biblioteki udostępniają osobne pakiety dla konkretnych architektur procesora lub interfejsy binarne aplikacji (ABI), i umieścić je w oddzielnych katalogach. Dzięki temu biblioteki niektórych architektur procesora, co pozwala na korzystanie z jej wersji. Dodawanie wielu wersji ABI biblioteki do skryptu kompilacji CMake, bez konieczności pisania wielu poleceń każdej wersji biblioteki, możesz użyć ścieżki ANDROID_ABI . Ta zmienna korzysta z listy domyślnych elementów AIs obsługiwanych przez NDK lub listy filtrowanej i interfejsów ABI ręcznie skonfigurować Gradle do użycia. Na przykład:

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 )

Aby narzędzie CMake mogło zlokalizować pliki nagłówkowe podczas kompilowania, musisz użyć polecenia include_directories() i uwzględnij ścieżkę do pliku pliki nagłówka:

include_directories( imported-lib/include/ )

Uwaga: jeśli chcesz spakować gotową bibliotekę, która nie jest zależność czasu kompilacji, np. podczas dodawania gotowej biblioteki, zależność imported-lib, nie musisz wykonywać wykonaj te instrukcje, aby połączyć z biblioteką.

Aby połączyć gotową bibliotekę z własną biblioteką natywną, dodaj ją do Polecenie target_link_libraries() w skrypcie kompilacji CMake:

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

Aby spakować gotową bibliotekę do pliku APK, musisz: ręcznie skonfigurować Gradle za pomocą bloku sourceSets, aby podaj ścieżkę do pliku .so. Po utworzeniu pliku APK może sprawdzić, które biblioteki Gradle znajdują się w Twoim pliku APK, za pomocą polecenia Analizator plików APK.

Uwzględnij inne projekty CMake

Jeśli chcesz utworzyć wiele projektów CMake i uwzględnić ich dane wyjściowe w Projektu na Androida, możesz użyć jednego pliku CMakeLists.txt jako skrypt kompilacji CMake (który jest link do Gradle) i dodać kolejne projekty CMake jako zależności tej kompilacji skrypt. Następujący skrypt kompilacji CMake najwyższego poziomu wykorzystuje add_subdirectory() do określenia kolejny plik CMakeLists.txt jako zależność kompilacji, a następnie linki w porównaniu z danymi wyjściowymi, tak jak w przypadku każdej innej gotowej biblioteki.

# 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 )

Wywołaj CMake z wiersza poleceń

Użyj tego polecenia, aby wywołać CMake i wygenerować projekt Ninja na zewnątrz w 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

To polecenie wygeneruje projekt Ninja, który można wykonać, aby utworzyć Biblioteki wykonywalne na Androida (pliki .so). CMAKE_TOOLCHAIN_FILE to wymagane do korzystania z obsługi CMake w NDK. W przypadku CMake 3.21 lub nowszego wbudowane jest narzędzie CMake Zamiast tego można użyć obsługi NDK, ale należy użyć innej grupy zmiennych jak opisano w dokumentacji CMake na temat kompilacji krzyżowej na Androida.