2016-06-13 77 views
14

所以我想在Android Studio上构建和测试一个与Android NDK的CMake。我可以让我的库进行编译,但它似乎并不想拉取任何第三方依赖关系。我一直在阅读工具链,并寻找更好的文档,没有运气。有人能告诉我我是否失踪?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的良好文档。

回答

3

该过程可能会很长,这取决于你的android技能。

一个例子可以是与此类似过程:

  • Crosscompile SFML。
  • 创建JNI桥
  • 生成带cmake的项目和编译
  • 您的文件复制到Android工作室。创建java加载库代码。

我想你已经crosscompiled 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 build目录和cmake的将填满你的变量 自动比如这个变量:

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桥:

在执行时间

Crosscompile您CMake的脚本和你的lib复制到应用程序/ src目录/主/ 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") 
} 
+0

因此,这里是我的build.gradle http://pastebin.com/K3r54H3b 我一直在关注过这个:http://tools.android.com/tech-docs/external-c-builds – ptDave

+0

我听起来很奇怪你的.gradle文件,我只对第三方交叉编译元素使用cmake。假设你的sfm lib是交叉编译形式的armv7或任何其他体系结构,你应该创建ndk模块。语法将取决于什么gradle版本使用,在我的情况下,我使用0.4.0 expermiental。 – uelordi

6

您可以添加更多关于: 的信息“但它似乎并不想将任何第三方依赖关系覆盖。”?

这一个:
https://github.com/googlesamples/android-ndk/tree/master-cmake/hello-libs 有静态和共享的第三方库,您可以尝试它。

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

  • link_directories(...)

则只是把LIB名直接进入

  • target_link_libraries (...)

也有效。确保你有适合你的ABI的libs,你打算支持你的应用[看起来你只是为一个ABI构建]。

+0

如果您正在编译多个ABI,您是否在jniLibs下有适当的子目录? – bph

+0

您的第二个方法是关于编辑CMakeLists.txt的问题吗? – bph

+0

是的,在CMakeLists.txt – Gerry