Ich bin ziemlich neu mit NDK + Gradle + CMake Integration und ich versuche zu verstehen, warum Verknüpfung nicht Symbole wie vorgesehen exportiert.Android NDK CMake Verknüpfung Probleme
Ich habe eine statische Bibliothek von einem CMakeLists.txt
gebaut, die nicht die Haupt CMakeLists.txt
ist.
Die Skripte tun so etwas wie:
# 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})
während CMakeLists.txt
innerhalb ${libs}/foo
ist die folgende:
# misc configuration of ${SRC}
add_library(foo STATIC ${SRC})
Das Skript funktioniert gut, ist es in der Lage libnative.so
zu verbinden, und ich bin in der Lage das finden generiert libfoo.a
. Alles scheint in Ordnung zu sein.
Ich versuche dann eine native Methode in foo.cpp
in foo Bibliothek enthalten sind, zu definieren: in foo Bibliothek definiert
extern "C" JNIEXPORT void JNICALL Java_com_mypackage_Controls_onTap(JNIEnv*, jobject, int x, int y) {
// log something
}
Aber ich bin nicht in der Lage die native Methode aufzurufen. Ich bekomme eine UnsatisfiedLinkError
zur Laufzeit. Wenn ich stattdessen (direkt durch Kopieren und Einfügen) die Methode in native.cpp verschiebe, dann ist alles in Ordnung.
Also im Grunde:
- Java -> Methode in native.cpp
- Java funktioniert -> Methode in native.cpp -> Methode in foo Bibliothek definiert arbeitet
- Java -> methode in foo bibliothek funktioniert nicht (
UnsatisfiedLinkError
)
Ich habe versucht, die exportierten Funktionen mit nm
zu inspizieren und es sieht so aus, dass foo.a
korrekt die native Funktion exportiert, wie ich
00011060 T Java_com_mypackage_Controls_onTap
Aber dieser Eintrag verschwindet aus libnative.so
sehen kann. Wenn ich stattdessen die Methode direkt in native.cpp definiere, kann ich sie mit nm auch auf libnative.so
richtig sehen.
Darüber hinaus Aufruf einer Methode in foo
Bibliothek von native.cpp
funktioniert wie vorgesehen, so dass die Bibliothek effektiv statisch verknüpft ist.
Ich bin nicht in der Lage, den Grund dafür zu verstehen, der Ansatz sollte in Ordnung sein, Sichtbarkeit sollte korrekt sein wie von JNIEXPORT
Makro festgelegt, so dass ich wirklich im Dunkeln tappen (und Gradle bietet keine Ausgabe der Kompilation Phase, so kann ich nicht verstehen, was passiert, aber die build.ninja Datei scheint korrekt)
Haben Sie versucht, 'set (CMAKE_VERBOSE_MAKEFILE auf)' hinzufügen? Aus Ihrer Erklärung ist es schwer zu sagen, was schiefgelaufen ist - entweder wird das Symbol von libnative.so entfernt, oder das Verknüpfen von libfoo.a wird insgesamt übersprungen. –
@AlexCohn Verknüpfung von libfoo.a wird nicht übersprungen, wie ich eine Methode von libfoo von libnative aufrufen kann und es richtig verknüpft und funktioniert. Es scheint, als ob das Symbol von außen sichtbar entfernt oder nicht exportiert wird, aber ich habe versucht, -visibility = default ohne Erfolg zu erzwingen. Leider wird der verwendete Generator nicht gemacht, daher gibt es kein Makefile. Ich kann den Aufruf Befehl sehen und es scheint richtig. Das wird erzeugt, indem native.o und libfoo.a gemocht werden. Ich habe wirklich keine Hinweise .. – Jack