Как создать статическую библиотеку (файл .a) в Android Studio 3.2 с помощью CMake

Теперь я создаю новый проект, включающий поддержку C++ в Android Studio 3.2, естественно, у него есть native-lib.cpp, CMakeLists.txt выглядит так:

add_library( # Sets 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)

теперь, если я соберу этот проект, я могу найти libnative-lib.so в некоторых директориях "отладки", это нормально, но мне нужна статическая библиотека, то есть файлы .a.

Измените ОБЩИЙ на СТАТИЧЕСКИЙ, эти файлы не будут генерироваться, что еще мне делать?

Документы CMake не упоминают другой способ, кроме add_library().

Все документы, которые я искал, говорят только о SHARED/STATIC.

Что я пропустил?

«При изменении SHARED на STATIC эти файлы не будут создаваться» Где вы это искали? Я ожидал, что он будет существовать под app/.externalNativeBuild/cmake/buildVariant/abi/src/main/cpp‌​/ (где buildVariant - один из ваших вариантов сборки, а abi - один из ABI, для которого вы строите).
Michael 23.10.2018 17:35

Вам нужно будет использовать статической библиотеки в общей библиотеке, чтобы она была полезна для приложения. Если вы не распространяете библиотеку, одна статическая библиотека бесполезна.

Dan Albert 23.10.2018 18:03
2
2
4 019
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Change SHARED to STATIC won't generate those files, what else should i do?

Вы можете получить статическую библиотеку, установив свою библиотеку как STATIC, а сгенерированный .a находится в <project-dir>/build/intermediates/cmake/debug/obj/<abi>/libnative-lib.a

add_library( native-lib
         STATIC
         src/main/cpp/native-lib.cpp)

Но, как сказал @Dan Albert, эта статическая библиотека сама по себе не очень полезна. Вам все равно нужно связать его с другими частями кода / библиотек, чтобы получить окончательную общую библиотеку, чтобы ваше приложение Android могло использовать.

Например,

add_library(my-shared-native SHARED src/main/cpp/other-source.cpp)
target_link_libraries(my-shared-native -Wl,--whole-archive native-lib -Wl,--no-whole-archive)

Затем на вашей стороне Java вы можете использовать этот общая библиотека, то есть libmy-shared-native.so.

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

Спасибо. Что означает '-Wl, - all-archive native-lib -Wl, - no-all-archive'?

Regis_AG 30.06.2021 11:08

Если добавить к @DanAlbert комментарий, вопрос не в том, насколько полезной может быть одна статическая библиотека. Проблема в том, что Android Studio через свой плагин Gradle по умолчанию не создает цель CMake, которая является библиотекой СТАТИЧЕСКИЙ.

К счастью, вы можете явно указать цели, который хотите создать, например

android { defaultConfig { externalNativeBuild { cmake {
    targets "native_staticlib"
} } } }

На самом деле создание статической библиотеки с помощью интегрированного externalNativeBuild не приносит особой пользы. Вы можете добиться того же, если запустите cmake --build из командной строки.

Ответ принят как подходящий

Во-первых, я хочу поблагодарить всех ребят, перечисленных выше, без вашего вдохновения я не смогу получить этот ответ.

Я записываю этот ответ НЕТ, потому что эти ответы неверны, я просто хочу помочь новичкам, таким как я, шаг за шагом, со всеми подробностями, которые должны знать.

Этот ответ был доказан в Android Studio 3.2.1 с CMake 3.4.1, я проверил трижды.

Теперь, если вы создадите новый проект с поддержкой C++, нажмите «Далее» до конца, вы получите CMakeLists.txt, который должен выглядеть так:

cmake_minimum_required(VERSION 3.4.1)

add_library( 
        native-lib
        SHARED
        src/main/cpp/native-lib.cpp)

find_library( 
        log-lib
        log)

target_link_libraries( 
        native-lib
        ${log-lib})

Измените ОБЩИЙ на СТАТИЧЕСКИЙ не будет выводить ни один файл .a, вы ничего не получите, даже файл .so (конечно, в этот файл нет библиотеки ОБЩИЙ).

Это "ошибка" Gradle / Android Studio, ответы выше уже упоминали об этом, если вы используете только CMake, вы определенно получите файл .a.

Хорошо, теперь мой ОБМАНЫВАТЬ:

У нас уже есть добавленная библиотека SHARED, затем мы добавляем библиотеку STATIC, которая использует тот же исходный файл. Добавьте ниже в свой CMakeLists.txt:

add_library(
        native-lib-static
        STATIC
        src/main/cpp/native-lib.cpp
)

"native-lib-static" можно заменить любым именем, кроме "native-lib", поскольку оно используется для версии SHARED.

Измените свой target_link_libraries следующим образом:

target_link_libraries(
        native-lib
        native-lib-static
        ${log-lib})

Gradle-> приложение-> сборка-> buildDebug / assemblyRelease

Тогда вы получите libnative-lib-static.a, в

app\.externalNativeBuild\cmake\debug(release)\<abi>\libnative-lib-static.a

Этот путь установлен в app\build.gradle:

android{
    defaultConfig{
         externalNativeBuild{
             CMake{

Банкомат Я не уверен, изменит ли Google его в будущем, но вы всегда можете поискать в папке проекта файлы *.a.

Не думаю, что на этот раз я что-то пропустил.

Все кредиты @Michael @Dan Albert @Alex Cohn @shizhen

явно указать цели сборки на уровне вашего приложения build.gradle

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # state here
                targets "native-lib" 
            }
        }
    }
}

выходной native-lib.a находится в обоих каталогах build/intermediates/cmake/debug/obj/<abi> и .externalNativeBuild/cmake/debug/<abi>

см. Google ndk-samples

Это должен быть ответ @ 2020

Felix.D 11.12.2020 07:57

Другие вопросы по теме