Android NDK, CMake с другими библиотеками

Итак, я пытаюсь создать и протестировать CMake с Android NDK на Android Studio. Я могу собрать свою библиотеку, но, похоже, она не хочет вытаскивать зависимые от сторонних сторон. Я читал инструментальную цепочку и искал лучшую документацию, без везения. Может кто-нибудь сказать мне, если я скучаю?

cmake_minimum_required(VERSION 3.4.1)

set(SFML_PATH ${ANDROID_NDK}/sources/sfml)
set(SFML_LIB_PATH ${SFML_PATH}/lib/${ANDROID_NDK_ABI_NAME})

set(SFML_LIB_SYSTEM ${SFML_LIB_PATH}/libsfml-system.so)
set(SFML_LIB_AUDIO ${SFML_LIB_PATH}/libsfml-audio.so)
set(SFML_LIB_GRAPHICS ${SFML_LIB_PATH}/libsfml-graphics.so)
set(SFML_LIB_NETWORK ${SFML_LIB_PATH}/libsfml-network.so)
set(SFML_LIB_WINDOW ${SFML_LIB_PATH}/libsfml-window.so)
set(SFML_LIB_ACTIVITY ${SFML_LIB_PATH}/libsfml-activity.so)
set(SFML_LIB_MAIN ${SFML_LIB_PATH}/libsfml-main.a)


set(SFML_LIBS ${SFML_LIB_SYSTEM} ${SFML_LIB_GRAPHICS} ${SFML_LIB_AUDIO} ${SFML_LIB_WINDOW} ${SFML_LIB_ACTIVITY})

include_directories(${SFML_PATH}/include)
link_directories(${SFML_LIB_PATH})

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

target_link_libraries(native-lib log ${SFML_LIBS})

#file(COPY ${SFML_LIBS} DESTINATION ${__android_install_path})
FOREACH(SFML_LIB ${SFML_LIB})
    execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${SFML_LIB}" "${LIBRARY_OUTPUT_PATH}/${SFML_LIB}" RESULT_VARIABLE __fileCopyProcess )
    MESSAGE("Lib: ${SFML_LIB}")
ENDFOREACH(SFML_LIB)

Выше мой CMakeLists.txt. Я немного взломал, чтобы заставить его скомпилировать SFML с помощью путей, поскольку я еще не нашел хорошую документацию с CMake и Android.

Ответ 1

Можете ли вы добавить дополнительную информацию для: "но похоже, что он не хочет вытаскивать зависимые от сторонних сторон".

этот:
https://github.com/googlesamples/android-ndk/tree/master-cmake/hello-libs имеет статические и общие сторонние библиотеки, вы можете попробовать.

Для общей зависимой библиотеки вам нужно будет упаковать их в APK, что делается внутри gradle, cmake этого не сделает.
Вышеприведенный пример показывает, что в основном они должны быть скопированы в ваше приложение /src/main/jniLibs, чтобы они были упакованы в apk и помещены на ваш Android-телефон/планшет. Во время выполнения они могут быть загружены.
Я попытался поместить группу библиотек в один каталог и использовать

  • link_directories (...)

то просто поместите имена lib непосредственно в

  • target_link_libraries (...)

также работает. Удостоверьтесь, что у вас есть правильные библиотеки для ABI, которые вы намерены поддерживать для своего приложения [похоже, что вы просто строите для одного ABI].

Ответ 2

Процесс может быть немного длинным, это будет зависеть от ваших навыков Android.

Пример может быть похож на этот процесс:

  • Crosscompile sfml.
  • Создайте свой jni-мост
  • Сгенерировать с помощью cmake проект и скомпилировать
  • Скопируйте файлы в андроид-студию. создать java-загрузку библиотеки.

Я предполагаю, что у вас есть crosscompiled sfml, и вы знаете, как работает кросс-компиляция, если я ошибаюсь, проверьте эту ссылку ниже:

Учебник: https://github.com/SFML/SFML/wiki/Tutorial:-Building-SFML-for-Android

Исходный код: https://github.com/SFML/SFML

Toolchain: https://github.com/SFML/SFML/blob/master/cmake/toolchains/android.toolchain.cmake

Изменения в вашем cmake: добавить этот файл

FIND_PACKAGE(SFML required)

В cmake поставьте свой каталог сборки SFML, и cmake заполнит ваши ПЕРЕМЕННЫЕ автоматически, например, такие переменные:

set(SFML_PATH ${ANDROID_NDK}/sources/sfml)
set(SFML_LIB_PATH ${SFML_PATH}/lib/${ANDROID_NDK_ABI_NAME})

set(SFML_LIB_SYSTEM ${SFML_LIB_PATH}/libsfml-system.so)
set(SFML_LIB_AUDIO ${SFML_LIB_PATH}/libsfml-audio.so)
set(SFML_LIB_GRAPHICS ${SFML_LIB_PATH}/libsfml-graphics.so)
set(SFML_LIB_NETWORK ${SFML_LIB_PATH}/libsfml-network.so)
set(SFML_LIB_WINDOW ${SFML_LIB_PATH}/libsfml-window.so)
set(SFML_LIB_ACTIVITY ${SFML_LIB_PATH}/libsfml-activity.so)
set(SFML_LIB_MAIN ${SFML_LIB_PATH}/libsfml-main.a) 

Существует два способа создания собственных приложений для студии Android:

Простой способ: Создать мост JNI:

Перекрестите ваш cmake script и скопируйте свою lib в app/src/main/jniLibs

добавить библиотеку во время выполнения

код:

try
{
  Log.v(LOG_TAG, "adding your library");
  System.loadLibrary(your_library);
}
catch(UnsatisfiedLinkError e)
{
 Log.e(LOG_TAG,e.getMessage());
}

Более полный способ (позволяет отлаживать библиотеку)

Создайте свой модуль ndk в gradle Пример

android.ndk {
    moduleName = "your_library"
    cppFlags.add("-fexceptions")
    //cppFlags.add("-std=c++11")
    //cFlags.add("-fopenmp")
    cppFlags.add("-I" + file("src/main/jni").absolutePath)
    stl = "gnustl_shared" // Which STL library to use: gnustl or stlport
    ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])
    String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi/"
    ldLibs.add(libsDir + "your_native_lib.so")
}