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-телефон/планшет. Во время выполнения они могут быть загружены.
Я попытался поместить группу библиотек в один каталог и использовать
то просто поместите имена 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")
}