Я не понимаю, как сказать Android Studio использовать эту библиотеку при попытке найти вызываемые функции
Чтобы использовать ваши родные библиотеки, т. Е. libmy-lib.so
для вашего случая, вам нужно загрузить эту общую библиотеку внутри вашей Java-части, как показано ниже.
static {
System.loadLibrary("my-lib");
}
Мой CMakeLists.txt правильный?
Да, это правильно, но не совсем идеально.
и как мне включить файл .h для функций
Чтобы вам было проще работать с добавляемыми заголовочными файлами, вам нужно немного настроить CMakelists.txt
. Например. Вы можете иметь структуру каталогов, как показано ниже, если у вас есть только app/src/main/cpp
, то вы можете просто удалить эти несвязанные каталоги и конфигурации.
app
├── CMakeLists.txt
└── src
├── foo
│ ├── CMakeLists.txt
│ ├── foo.cpp
│ └── foo.h
├── main
│ └── cpp
│ ├── CMakeLists.txt
│ └── my-lib.cpp
└── test
├── CMakeLists.txt
└── google_test_classXXX.cpp
Затем вам нужно настроить app/CMakelists.txt
, как показано ниже.
# set the root directory as ${CMAKE_CURRENT_SOURCE_DIR} which is a
# CMAKE build-in function to return the current dir where your CMakeLists.txt is.
# Specifically, it is "<your-path>/App/"
set(APP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
# set your 3 other root dirs, i.e. foo, main and test under app/src.
set(APP_ROOT_SRC_DIR ${APP_ROOT_DIR}/src)
set(APP_ROOT_FOO_DIR ${APP_ROOT_SRC_DIR}/foo)
set(APP_ROOT_MAIN_DIR ${APP_ROOT_SRC_DIR}/main)
set(APP_ROOT_TEST_DIR ${APP_ROOT_SRC_DIR}/test)
# set your include paths into "SHARED_INCLUDES" variable so that you can quote your header file without adding its relative paths.
set(SHARED_INCLUDES
${APP_ROOT_FOO_DIR}
# ${APP_ROOT_FOO_DIR}/<your-other-child-dirs>
${APP_ROOT_MAIN_DIR}
${APP_ROOT_MAIN_DIR}/cpp
# ${APP_ROOT_MAIN_DIR}/<your-other-child-dirs>
${APP_ROOT_TEST_DIR}
# ${APP_ROOT_TEST_DIR}/<your-other-child-dirs>
)
# This function will have effect to all the downstream cmakelist files.
include_directories(${SHARED_INCLUDES})
add_library(my-lib SHARED src/main/cpp/my-lib.cpp )
target_link_libraries(my-lib z crypto)
target_link_libraries(my-lib ${CMAKE_CURRENT_SOURCE_DIR}/../libs/libmine.a)
# remember to include downstream cmakelist files for foo, main and test.
add_subdirectory(${APP_ROOT_FOO_DIR} bin-dir)
add_subdirectory(${APP_ROOT_MAIN_DIR} bin-dir)
add_subdirectory(${APP_ROOT_TEST_DIR} bin-dir)
---- Edited ----
Для того, чтобы связать prebuild .a libs.
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries(my-lib -Wl,--whole-archive ${CMAKE_CURRENT_SOURCE_DIR}/../libs/libmine.a -Wl,--no-whole-archive)
---- Отредактировано, чтобы ответить на ваши три вопроса ----
Что входит в CMakeLists.txt внутри директории cpp?
Это должно быть в каталоге cpp или в главном каталоге?
Теоретически, вы можете просто иметь один CMakelists.txt
для всех ваших каталогов исходного кода и каталогов заголовков, но как только ваш проект разовьется в очень большом масштабе, это все-в-одном CMakelists.txt
станет довольно сложным и не читаемым и ремонтопригоден. Обычно каждый модуль cmake должен иметь свой собственный файл CMakeLists.txt
, чтобы он был модульным и более простым в управлении. Например. cpp
dir имеет один CMakeLists.txt
для управления всеми его подкаталогами, если таковые имеются, так же, как и main
и test
"module"
А как мне включить .h файл моей .a lib - #include не работает.
Как я упоминал выше, вам нужно настроить SHARED_INCLUDES
, чтобы добавить ваши относительные пути к заголовкам (.h
) вашего .a
, чтобы вы могли просто использовать #include <xxx.h>
для включения заголовка.
set(SHARED_INCLUDES
${APP_ROOT_FOO_DIR}
# ${APP_ROOT_FOO_DIR}/<your-other-child-dirs>
${APP_ROOT_MAIN_DIR}
${APP_ROOT_MAIN_DIR}/cpp
# ${APP_ROOT_MAIN_DIR}/<your-other-child-dirs>
${APP_ROOT_TEST_DIR}
# ${APP_ROOT_TEST_DIR}/<your-other-child-dirs>
)
Установите ваши пути включения в переменную "SHARED_INCLUDES", чтобы вы могли заключить в кавычки файл заголовка без добавления его относительных путей.
Изменить, чтобы ответить на ваш вопрос о том, как настроить архитектуру
вы можете настроить свои цели внутри build.gradle
, как показано ниже:
defaultConfig {
externalNativeBuild {
cmake {
...
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
...
}
}
}
Процесс сборки CMake будет принимать каждый ABI один за другим. Переменная ${ANDROID_ABI}
внутри CMakelists.txt
может сказать вам текущий ABI (архитектура), который она строит. И вы также можете использовать эту переменную для настройки PATH вашей библиотеки, если вам нужно.
например. Эта переменная ${ANDROID_ABI}
внутри
target_link_libraries(${SHARED_LIBRARY_NAME} -Wl,--whole-archive ${CMAKE_CURRENT_SOURCE_DIR}/../libs/${ANDROID_ABI}/libmine.a -Wl,--no-whole-archive)
будет заменено на armeabi-v7a
, arm64-v8a
, x86
или x86_64
во время сборки.