web-dev-qa-db-ja.com

Android NDK、他のライブラリとのCMake

Android NDK on Android Studioで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です。 CMakeとAndroidのドキュメントがまだ見つからないため、パスを使用してSFMLでコンパイルできるように、少しハッキングを行いました。

14
ptDave

「しかし、それはサードパーティの依存関係を引き継ぐことを望んでいないようです。」のためにさらに情報を追加してもらえますか?

これです:
https://github.com/googlesamples/Android-ndk/tree/master/hello-libs は静的で共有されたサードパーティライブラリを持っているので、試してみてください。

共有依存ライブラリの場合、それらをAPKにパックする必要があります。これはGradle内で行われ、cmakeはそれを行いません。
上記の例は、基本的にそれらをapp/src/main/jniLibsにもコピーして、apkにパックして、Android電話にプッシュする必要があることを示しています。/tablet。実行時にロードできます。
ライブラリのグループを1つのディレクトリに配置して、

  • link_directories(...)

次に、ライブラリ名を直接に入力します

  • target_link_libraries(...)

も動作します。アプリをサポートする予定のABIに適切なライブラリがあることを確認してください[1つのABIのためにビルドしているように見えます]。

6
Gerry

プロセスはあなたのAndroidスキルに依存します。).

例は次のプロセスに似ています。

  • Sfmlをクロスコンパイルします。
  • JNIブリッジを作成する
  • プロジェクトをcmakeで生成してコンパイルする
  • ファイルをAndroid studio。create Java loading library code。

私はあなたが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スタジオネイティブアプリを作成するには2つの方法があります。

簡単な方法: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")
}
3
uelordi