gpt4 book ai didi

Android CMake 使用预构建 .a 库

转载 作者:搜寻专家 更新时间:2023-11-01 08:20:58 24 4
gpt4 key购买 nike

我对 CMake 完全陌生,并且经常使用 NDK。我想出了编写我的 JNI 接口(interface)并使用 2 个方法的方法,它们是 C 库的一部分。我将这个库编译为静态库并得到了 .a 文件。现在我有点迷路了,因为我不明白如何告诉 Android Studio 在尝试查找被调用的函数时使用这个库。

这是我当前的 CMakeLists.txt,它位于“app”模块文件夹中。

cmake_minimum_required(VERSION 3.4.1)

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)

在编译时,我收到警告,指出无法找到对被调用函数的引用。我的 CMakeLists.txt 是否正确以及如何包含函数的 .h 文件?在此先感谢您的帮助!

最佳答案

I don't understand how to tell Android Studio to use this library when trying to find the called functions

为了使用您的本地库,即 libmy-lib.so对于您的情况,您需要将此共享库加载到您的 java 部分中,如下所示。

    static {
System.loadLibrary("my-lib");
}

Is my CMakeLists.txt correct ?

是的,它是正确的,但并不完美。

and how do I include the .h file for the functions

为了方便自己添加头文件include,需要配置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)

---- 已编辑以回答您的三个问题----

What is part of the CMakeLists.txt inside of the cpp directoy? Does it need to be in the cpp directory or in the main directory?

理论上,你可以只拥有一个CMakelists.txt对于您所有的源代码目录和 header 目录,但是一旦您的项目发展到非常大的规模,这个一体式 CMakelists.txt将变得相当复杂,不可读和不可维护。通常,每个 cmake 模块都应该有自己的 CMakeLists.txt文件,使其模块化并更易于管理。例如。 cpp dir 有一个 CMakeLists.txt管理它的所有子目录,如果有的话,也是如此 maintest “模块”。

And how do I include a .h file of my .a lib - #include does not work.

正如我上面提到的,你需要配置SHARED_INCLUDES将您的相对路径添加到您的 .h 的 header ( .a ) , 这样你就可以简单地使用 #include <xxx.h>用于 header 包含。

    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(架构)。如果需要,您还可以使用此变量来配置您的库路径。

例如此变量 ${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 , x86x86_64在构建期间。

关于Android CMake 使用预构建 .a 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51188683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com