2016-06-13 74 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