【问题标题】:Android NDK, CMake with other librariesAndroid NDK、CMake 与其他库
【发布时间】:2016-10-13 08:25:05
【问题描述】:

所以我正在尝试在 Android Studio 上使用 Android NDK 构建和测试 CMake。我可以编译我的库,但它似乎不想拉出任何第三方依赖项。我一直在阅读工具链并寻找更好的文档,但没有运气。如果我失踪了,谁能告诉我?

cmake_minimum_required(VERSION 3.4.1)

set(SFML_PATH ${ANDROID_NDK}/sources/sfml)
set(SFML_LIB_PATH ${SFML_PATH}/lib/${ANDROID_NDK_ABI_NAME})

set(SFML_LIB_SYSTEM ${SFML_LIB_PATH}/libsfml-system.so)
set(SFML_LIB_AUDIO ${SFML_LIB_PATH}/libsfml-audio.so)
set(SFML_LIB_GRAPHICS ${SFML_LIB_PATH}/libsfml-graphics.so)
set(SFML_LIB_NETWORK ${SFML_LIB_PATH}/libsfml-network.so)
set(SFML_LIB_WINDOW ${SFML_LIB_PATH}/libsfml-window.so)
set(SFML_LIB_ACTIVITY ${SFML_LIB_PATH}/libsfml-activity.so)
set(SFML_LIB_MAIN ${SFML_LIB_PATH}/libsfml-main.a)


set(SFML_LIBS ${SFML_LIB_SYSTEM} ${SFML_LIB_GRAPHICS} ${SFML_LIB_AUDIO} ${SFML_LIB_WINDOW} ${SFML_LIB_ACTIVITY})

include_directories(${SFML_PATH}/include)
link_directories(${SFML_LIB_PATH})

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

target_link_libraries(native-lib log ${SFML_LIBS})

#file(COPY ${SFML_LIBS} DESTINATION ${__android_install_path})
FOREACH(SFML_LIB ${SFML_LIB})
    execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${SFML_LIB}" "${LIBRARY_OUTPUT_PATH}/${SFML_LIB}" RESULT_VARIABLE __fileCopyProcess )
    MESSAGE("Lib: ${SFML_LIB}")
ENDFOREACH(SFML_LIB)

上面是我的 CMakeLists.txt。我做了一些修改,让它与带有路径的 SFML 一起编译,因为我还没有找到关于 CMake 和 Android 的好的文档。

【问题讨论】:

    标签: android-ndk cmake


    【解决方案1】:

    您能否为以下内容添加更多信息: “但它似乎不想拉出任何第三方依赖项。”?

    这个:
    https://github.com/googlesamples/android-ndk/tree/master/hello-libs 有静态和共享的 3rd 方库,你可以试试。

    对于共享依赖库,你需要将它们打包到APK中,这是在gradle内部完成的,cmake不会这样做。
    上面的例子表明,基本上它们也需要复制到您的 app/src/main/jniLibs 中,以便将它们打包到 apk 中,并推送到您的 android 手机/平板电脑。在运行时可以加载它们。
    我试图将一组库放在一个目录中,并使用

    • link_directories(...)

    然后只需将库名称直接放入

    • target_link_libraries(...)

    也可以。确保您为您的应用程序支持的 ABI 提供了正确的库 [看起来您只是在为一个 ABI 构建]。

    【讨论】:

    • 如果您正在为多个 ABI 编译,您在 jniLibs 下是否有相应的子目录?
    • 您的第二种方法是在谈论编辑 CMakeLists.txt 吗?
    • 是的,在 CMakeLists.txt 中
    • 我不确定 AS 是否曾经自动生成 app/src/main/jniLibs 目录,但它似乎不再是了
    • 链接已损坏。
    【解决方案2】:

    这个过程可能会有点长,这取决于你的 android 技能。

    一个例子可能类似于这个过程:

    • 交叉编译 sfml。
    • 创建您的 jni 桥
    • 用 cmake 生成项目并编译
    • 将文件复制到 android studio。创建java加载库代码。

    我猜你已经交叉编译了 sfml 并且你知道交叉编译过程是如何工作的,如果我错了,请查看以下链接:

    教程: https://github.com/SFML/SFML/wiki/Tutorial:-Building-SFML-for-Android

    源代码: https://github.com/SFML/SFML

    工具链: https://github.com/SFML/SFML/blob/master/cmake/toolchains/android.toolchain.cmake

    您的 cmake 更改: 添加这个文件

    FIND_PACKAGE(SFML required)
    

    在 cmake 中放入您的 SFML 构建目录,cmake 将填充您的 VARIABLES 自动例如这个变量:

    set(SFML_PATH ${ANDROID_NDK}/sources/sfml)
    set(SFML_LIB_PATH ${SFML_PATH}/lib/${ANDROID_NDK_ABI_NAME})
    
    set(SFML_LIB_SYSTEM ${SFML_LIB_PATH}/libsfml-system.so)
    set(SFML_LIB_AUDIO ${SFML_LIB_PATH}/libsfml-audio.so)
    set(SFML_LIB_GRAPHICS ${SFML_LIB_PATH}/libsfml-graphics.so)
    set(SFML_LIB_NETWORK ${SFML_LIB_PATH}/libsfml-network.so)
    set(SFML_LIB_WINDOW ${SFML_LIB_PATH}/libsfml-window.so)
    set(SFML_LIB_ACTIVITY ${SFML_LIB_PATH}/libsfml-activity.so)
    set(SFML_LIB_MAIN ${SFML_LIB_PATH}/libsfml-main.a) 
    

    制作android studio原生应用有两种方式:

    简单的方法: 创建 JNI 桥:

    交叉编译你的 cmake 脚本并将你的 lib 复制到 app/src/main/jniLibs

    在执行时添加库

    代码:

    try
    {
      Log.v(LOG_TAG, "adding your library");
      System.loadLibrary(your_library);
    }
    catch(UnsatisfiedLinkError e)
    {
     Log.e(LOG_TAG,e.getMessage());
    }
    

    更完整的方式(允许调试库)

    在 gradle 中创建你的 ndk 模块 例子

    android.ndk {
        moduleName = "your_library"
        cppFlags.add("-fexceptions")
        //cppFlags.add("-std=c++11")
        //cFlags.add("-fopenmp")
        cppFlags.add("-I" + file("src/main/jni").absolutePath)
        stl = "gnustl_shared" // Which STL library to use: gnustl or stlport
        ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "z"])
        String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi/"
        ldLibs.add(libsDir + "your_native_lib.so")
    }
    

    【讨论】:

    • 所以这是我的 build.gradle pastebin.com/K3r54H3b 我一直在关注这个:tools.android.com/tech-docs/external-c-builds
    • 我听起来很奇怪你的 .gradle 文件,我只将 cmake 用于 3rdparty 交叉编译元素。假设您的 sfm lib 是从 armv7 或任何其他架构交叉编译的,您应该创建 ndk 模块。语法将取决于使用的 gradle 版本,在我的情况下,我使用 0.4.0 expermiental。
    猜你喜欢
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    相关资源
    最近更新 更多