在 NDK w/gradle 上编译两个项目,其中一个依赖于另一个的二进制文件

Posted

技术标签:

【中文标题】在 NDK w/gradle 上编译两个项目,其中一个依赖于另一个的二进制文件【英文标题】:Compile two projects on NDK w/ gradle, one of which depends on the other's binary 【发布时间】:2018-04-25 01:42:39 【问题描述】:

我正在像这样在 gradle 中编译一个库:

externalNativeBuild 

        // Encapsulates your CMake build configurations.
        cmake 
            // Provides a relative path to your CMake build script.
            path "../../JRTPLIB/CMakeLists.txt"
        
    

我需要编译另一个源,可能使用 cmake 或任何其他工具,也在 gradle 内部,它将链接到上面的 lib (JRTPLIB) 中的编译对象。

显而易见的方法是将上述库的源代码包含在我要使用的库中并仅链接,但我需要单独进行。

另一种方法是依赖android/app/build/intermediates/cmake/... 处生成的库对象,但首先,它应该在此文件夹中有一个调试二进制文件和一个发布文件,这使得链接更加复杂,其次,它不是一个优雅的解决方案。

那该怎么做呢?

【问题讨论】:

cmake.org/cmake/help/v3.0/command/add_subdirectory.html @Michael 所以我应该让项目 2 编译项目 1 然后使用它的二进制文件?如果我的 android 项目同时需要项目 1 和项目 2 的二进制文件怎么办? 我建议您为每个库创建一个目录,每个库都有自己的CMakeLists.txtadd_library 用于构建 .so 文件或其他文件。然后在父目录中添加主目录CMakeLists.txt(您在 gradle 脚本中指出的那个)并让它为每个库执行add_subdirectory @Michael 我添加了 add_subdirectory,但是当我在主项目上运行 cmake 时,它​​只是生成子目录的 make 文件,然后尝试构建主项目。如何首先构建依赖项?我认为 add_subdirectory 会构建它们 【参考方案1】:

这是一个简单的例子,它完成了我认为你正在尝试做的事情。

正在构建两个库并将其打包到应用程序中,其中第二个库依赖于第一个库。我选择将 lib1 和 lib2 作为当前项目的一部分,但它们实际上可以位于任何地方。

app/CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_subdirectory(src/main/cpp/lib1)
add_subdirectory(src/main/cpp/lib2)

app/src/main/cpp/lib1/CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
             native-lib1
             SHARED
             native-lib1.cpp )

target_include_directories(native-lib1 PUBLIC $CMAKE_CURRENT_SOURCE_DIR)

app/src/main/cpp/lib2/CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.
             native-lib2
             SHARED
             native-lib2.cpp )

find_library(log-lib log)

# native-lib2 depends on log and native-lib1
target_link_libraries(native-lib2 $log-lib native-lib1)

app/src/main/cpp/lib1/native-lib1.h

#pragma once

int foo();

app/src/main/cpp/lib1/native-lib1.cpp

#include "native-lib1.h"

int foo()

    return 42;


app/src/main/cpp/lib2/native-lib2.cpp

#include <jni.h>
#include <android/log.h>
#include <string>
#include "native-lib1.h"

extern "C" JNIEXPORT jstring JNICALL Java_com_example_cmaketwolibs_MainActivity_stringFromJNI(
    JNIEnv *env, jobject thiz) 

    // Call function from native-lib1
    __android_log_print(ANDROID_LOG_WARN,
                        "native-lib2", "Calling native-lib1\'s foo(): %d",
                        foo());

    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());

【讨论】:

非常感谢你。写的很好,希望能多加分 只有一个问题...log 是什么? NDK 自带的 google 的日志库。我正在使用__android_log_print,因此为什么需要该库。 太棒了,学到了新东西,NDK的例子也很有帮助。谢谢!!!!

以上是关于在 NDK w/gradle 上编译两个项目,其中一个依赖于另一个的二进制文件的主要内容,如果未能解决你的问题,请参考以下文章

Cmake 无法在 qt creator/collect2 上编译简单的测试程序:错误:ld

ffmpeg neon 在 android 上编译 - 汇编错误

运行./configure时在Windows上编译FFmpeg错误

尽管在 macBookPro 上编译和运行完美,但在 Mac mini 上编译项目的桥接头问题

尽管在 macBookPro 上编译和运行完美,但在 Mac mini 上编译项目的桥接头问题

为啥heroku无法在项目上编译构建?