NDK + Gradle + CMakeの統合が新しくなりました。リンクが意図したとおりにシンボルをエクスポートしない理由を理解しようとしています。Android NDK CMakeのリンクの問題
CMakeLists.txt
で構築されたスタティックライブラリは、CMakeLists.txt
ではありません。
# main CMakeLists.txt
add_subdirectory(${LIBS}/foo libs}
add_library(native SHARED native.cpp)
# omitting standard android libraries
target_link_libraries(native foo ${android-lib} ${log-lib})
が${libs}/foo
内部CMakeLists.txt
ながら、以下の通りである:
スクリプト
は何かのように行います# misc configuration of ${SRC}
add_library(foo STATIC ${SRC})
スクリプトが正常に動作し、それがlibnative.so
をリンクすることができますし、私は見つけることができますよ生成されたlibfoo.a
。すべてがうまく見えます。
私はその後、FOOライブラリに含まれるfoo.cpp
でネイティブメソッドを定義しよう:
extern "C" JNIEXPORT void JNICALL Java_com_mypackage_Controls_onTap(JNIEnv*, jobject, int x, int y) {
// log something
}
しかし、私はFOOライブラリで定義されたネイティブメソッドを呼び出すことができませんよ。実行時にUnsatisfiedLinkError
が表示されます。代わりに、メソッドをnative.cppに(直接コピーして貼り付けて)移動すれば、すべてうまく行きます。
だから、基本的には:> native.cppでの方法 - -
- のJava -
- Javaの作品 native.cppで>方法fooライブラリの - >メソッドが機能しません(
UnsatisfiedLinkError
)
私はnm
でエクスポート機能を検査しようとしたと私は
00011060 T Java_com_mypackage_Controls_onTap
を見ることができるように、そのfoo.a
が正しくネイティブ関数をエクスポートします。しかし、このエントリはlibnative.so
から消えるように見えます。代わりにnative.cppに直接メソッドを定義すると、libnative.so
のnmでも正しく表示できます。
さらに、foo
ライブラリの任意のメソッドをnative.cpp
から呼び出すと、ライブラリが効果的に静的にリンクされます。
私はこれの背後にある理由を理解することができませんが、アプローチはうまくいくはずです。可視性はJNIEXPORT
マクロで指定されているように正確でなければなりません。だから私は暗闇の中で本当に頑張っています(そしてGradleはコンパイルフェーズでは何が起こっているのか理解できませんが、build.ninjaファイルは正しいようです)
は、あなたが ''セット(上CMAKE_VERBOSE_MAKEFILE)を追加しようとしたことがありますか?あなたの説明から、何がうまくいかないかを知るのは難しいです。シンボルがlibnative.soから削除されているか、libfoo.aのリンクが完全にスキップされています。 –
libfoo.aの@AlexCohnリンクは、libnativeからlibfooのメソッドを呼び出すことができ、正しくリンクして動作するため、スキップされません。それはシンボルが剥奪されているか、外から目に見えないようにエクスポートされているようですが、私は強制的に-fvisibility = defaultを成功させようとしました。残念ながら、使用されたジェネレータはメイクファイルではありません。私は呼び出しコマンドを見ることができ、それは正しいようです。 soはnative.oとlibfoo.aを好きにして生成されます。私は実際に手がかりを得ていませんでした。 – Jack