【问题标题】:How to create a static library (.a file) in Android Studio 3.2 with CMake如何使用 CMake 在 Android Studio 3.2 中创建静态库(.a 文件)
【发布时间】:2019-03-27 21:06:00
【问题描述】:

现在我在 Android Studio 3.2 中创建了一个包含 c++ 支持的新项目,它自然有native-lib.cppCMakeLists.txt 看起来像这样:

add_library( # Sets the name of the library.
    native-lib

    # Sets the library as a shared library.
    SHARED

    # Provides a relative path to your source file(s).
    src/main/cpp/native-lib.cpp)

现在如果我构建这个项目,我可以在一些“调试”目录中找到libnative-lib.so,这没关系,但我想要静态库,即.a 文件。

SHARED改为STATIC不会生成这些文件,我还应该怎么做?

除了add_library(),CMake 文档没有提及其他方式。

我搜索的每个文档都只谈论SHARED/STATIC

我错过了什么?

【问题讨论】:

  • “将 SHARED 更改为 STATIC 不会生成这些文件” 你在哪里找的?我希望它存在于app/.externalNativeBuild/cmake/buildVariant/abi/src/main/cpp/ 下(其中buildVariant 是您的构建变体之一,abi 是您正在构建的ABI 之一)。
  • 您需要在共享库中使用静态库,它才能对应用程序有用。除非你分发库,否则单独的静态库是没有用的。

标签: android cmake android-ndk java-native-interface static-libraries


【解决方案1】:

除了@DanAlbert 的comment,问题不在于单独的静态库有多大用处。问题在于,默认情况下,Android Studio 通过其 Gradle 插件不会构建作为 STATIC 库的 CMake 目标。

幸运的是,您可以明确指定要生成的targets,例如

android { defaultConfig { externalNativeBuild { cmake {
    targets "native_staticlib"
} } } }

实际上,通过集成的externalNativeBuild构建静态库并没有太大的附加值。如果你从命令行运行cmake --build,你可以达到同样的效果。

【讨论】:

    【解决方案2】:

    在您的应用级 build.gradle 中明确声明构建目标

    android {
        defaultConfig {
            externalNativeBuild {
                cmake {
                    # state here
                    targets "native-lib" 
                }
            }
        }
    }
    

    输出native-lib.a 位于build/intermediates/cmake/debug/obj/<abi>.externalNativeBuild/cmake/debug/<abi> 目录中

    google ndk-samples

    【讨论】:

    • 这应该是@2020的答案
    【解决方案3】:

    首先,我要感谢以上所有的人,没有你们的启发,我无法得到这个答案。

    我把这个答案写下来不是因为这些答案是错误的,我只是想帮助像我这样的新手,一步一步来,所有细节都应该知道。

    这个答案在 Android Studio 3.2.1CMake 3.4.1 中得到证明,我检查了三次。

    现在如果你创建一个支持C++的新项目,一直点击“下一步”,你会得到一个CMakeLists.txt,它应该是这样的:

    cmake_minimum_required(VERSION 3.4.1)
    
    add_library( 
            native-lib
            SHARED
            src/main/cpp/native-lib.cpp)
    
    find_library( 
            log-lib
            log)
    
    target_link_libraries( 
            native-lib
            ${log-lib})
    

    SHARED改为STATIC不会输出任何.a文件,你什么也得不到,甚至没有.so文件(当然,没有SHARED 库被添加到这个文件中)。

    这是 Gradle/Android Studio 的“错误”,上面的答案已经提到了,如果你单独使用 CMake,你肯定会得到一个@987654327 @文件。

    好的,现在是我的TRICK

    我们已经有一个添加共享库,然后我们添加一个静态库,它使用相同的源文件。在您的CMakeLists.txt 中添加以下内容:

    add_library(
            native-lib-static
            STATIC
            src/main/cpp/native-lib.cpp
    )
    

    “native-lib-static”可以替换为除“native-lib”以外的任何名称,因为它用于 SHARED 版本。

    像这样更改您的target_link_libraries

    target_link_libraries(
            native-lib
            native-lib-static
            ${log-lib})
    

    Gradle->app->build->assembleDebug/assembleRelease

    然后你会得到libnative-lib-static.a,在

    app\.externalNativeBuild\cmake\debug(release)\<abi>\libnative-lib-static.a
    

    这个路径设置在app\build.gradle:

    android{
        defaultConfig{
             externalNativeBuild{
                 CMake{
    

    ATM 我不确定 Google 将来是否会更改它,但您始终可以在项目文件夹中搜索 *.a 文件。

    这次我想我什么都不会错过。

    感谢@Michael @Dan Albert @Alex Cohn @shizhen

    【讨论】:

    • 这对我现在不起作用,Android Studio 版本是 2020.3.1,在 mac 上,M1 芯片。 Suen 的回答对我有用。
    • 这确实对我有用,但是我在 app/.cxx// (Android Studio 2020.3.1) 找到了静态库
    【解决方案4】:

    将SHARED更改为STATIC不会生成这些文件,我该怎么办?

    您可以通过将您的库设置为STATIC 来获得静态库,并且生成的.a 位于&lt;project-dir&gt;/build/intermediates/cmake/debug/obj/&lt;abi&gt;/libnative-lib.a

    add_library( native-lib
             STATIC
             src/main/cpp/native-lib.cpp)
    

    但是,就像@Dan Albert 所说,这个静态库本身并没有多大用处。您仍然需要将它与您的代码/库的其他部分链接以生成最终的共享库,以便您的 Android 应用可以使用。

    例如

    add_library(my-shared-native SHARED src/main/cpp/other-source.cpp)
    target_link_libraries(my-shared-native -Wl,--whole-archive native-lib -Wl,--no-whole-archive)
    

    然后在您的 Java 端,您可以使用这个共享库,即libmy-shared-native.so

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

    【讨论】:

    • 谢谢。 '-Wl,--whole-archive native-lib -Wl,--no-whole-archive' 是什么意思?
    猜你喜欢
    • 2012-09-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    相关资源
    最近更新 更多