связывание libc с кодом JNI на встроенной платформе Linux (GuruPlug) - PullRequest
1 голос
/ 31 октября 2011

Я пытаюсь скомпилировать простое приложение JNI на встроенной платформе Linux (компьютер GuruPlug), но по какой-то причине он не связывается должным образом с libc. Java-программа, которую я компилирую, называется Test.java:

public class Test {
    static {
        System.loadLibrary("Test");
    }

    public static void main(String[] args) {
        new Test().printMessage();
    }

    public native void printMessage();
}

Реализация printMessage () находится в Test.c:

#include <jni.h>
#include <stdio.h>
#include "Test.h"

JNIEXPORT void JNICALL Java_Test_printMessage(JNIEnv *env, jobject obj)
{
    printf("Message 123...\n");
}

Я компилирую Test.c с помощью следующей команды в оболочке bash:

gcc -g -shared -static -lc -Wl,-soname,libTest.so -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ Test.c -o libTest.so

Когда я запускаю указанную выше команду, я получаю сообщение об ошибке «Перемещение R_ARM_TLS_LE32 не разрешено в общем объекте». Полное сообщение об ошибке:

/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabi/4.4.5/../../../libc.a(dl-tsd.o)(.text+0x18): R_ARM_TLS_LE32 relocation not permitted in shared object

Несмотря на сообщение об ошибке, JSI-файл .so по-прежнему записывается компилятором, но при запуске приложения Java выдается следующее сообщение об ошибке:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/jni/libTest.so: /usr/lib/jni/libTest.so: unexpected reloc type 0x03
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1675)
        at java.lang.Runtime.loadLibrary0(Runtime.java:840)
        at java.lang.System.loadLibrary(System.java:1047)
        at Test.<clinit>(Test.java:3)
Could not find the main class: Test. Program will exit.

Кто-нибудь знает, как это исправить? Следует признать, что приведенный выше код является игрушечным примером, но мне нужно получить реальную библиотеку JNI, компилируемую на этой платформе, а настоящая библиотека JNI зависит от libc. Я не могу решить эту основную проблему связывания libc с библиотекой JNI. Любые предложения будут с благодарностью.

Спасибо!

1 Ответ

2 голосов
/ 01 ноября 2011

gcc -g -shared -static -lc -Wl,-soname,libTest.so -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ Test.c -o libTest.so

Есть несколько проблем с командной строкой выше:

  • -shared и -static являются взаимоисключающими, а второй перекрывает первый
  • при связывании совместно используемых библиотек вы хотите -fPIC на большинстве архитектур
  • -lc находится не в том месте (должно следовать вашим источникам, а не предшествовать им), и в любом случае не является необходимым: gcc добавит его автоматически
  • вам строго не нужен -soname; это просто бесполезный беспорядок

Правильная команда:

gcc -g -shared -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux \
  Test.c -o libTest.so
...