我不明白在尝试查找被调用函数时如何告诉 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)
----编辑----
有关如何链接预构建的 .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
dir 有一个CMakeLists.txt
来管理其所有子目录(如果有的话),main
“test
模块”也是如此。
以及如何包含我的 .a lib 的 .h 文件 - #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。
eg 这个变量${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
在构建期间。