我不明白在尝试查找被调用函数时如何告诉 Android Studio 使用此库
为了使用您的本机库,即libmy-lib.so,您需要在您的 java 部分中加载此共享库,如下所示。
static {
System.loadLibrary("my-lib");
}
我的 CMakeLists.txt 是否正确?
是的,它是正确的,但并不完美。
以及如何包含函数的 .h 文件
为了方便自己添加头文件includes,需要稍微配置一下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)
----已编辑----
关于如何链接 prebuild .a 库。
# 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)
----已编辑以回答您的三个问题----
cpp 目录中的 CMakeLists.txt 的一部分是什么?
需要在cpp目录下还是在主目录下?
理论上,您的所有源代码目录和标头目录都可以只有一个CMakelists.txt,但是一旦您的项目发展到非常大的规模,这个一体化的CMakelists.txt 将变得相当复杂且不可读并且可维护。通常,每个 cmake 模块都应该有自己的CMakeLists.txt 文件,以便模块化并且更易于管理。例如。 cpp 目录有一个CMakeLists.txt 来管理其所有子目录(如果有),main 和test“模块”也是如此。
以及如何包含我的 .a 库的 .h 文件 - #include 不起作用。
正如我上面提到的,您需要配置SHARED_INCLUDES 以将您的相对路径添加到您的.a 的标头(.h),这样您就可以简单地使用#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。 CMakelists.txt 中的变量 ${ANDROID_ABI} 可以告诉您它正在构建的当前 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。