В настоящее время я пытаюсь интегрировать сервер NFS в некоторый код, работающий на RTEMS 4.9.2
на POWER PC 5200
, Это будет сложно кратко объяснить, так что терпите меня.
В настоящее время RTEMS реализует клиент NFS через файл nfs.c. Для того чтобы активировать интерфейс командной строки и иметь возможность использовать mount -t nfs ...
вариант, который нужно добавить #define CONFIGURE_SHELL_MOUNT_NFS
к вашему файлу конфигурации и свяжите файлы rtems nfs с -lnfs
, Увидеть Вот Больше подробностей. Правильное выполнение этого позволяет нам реализовать клиент RTEMS nfs, и из командной строки мы можем подключить удаленный диск.
Мы не раскрываем командную строку RTEMS в нашей программе, поэтому мы хотели бы иметь возможность напрямую использовать интерфейс nfs. RTEMS libs предоставляет librtemsNfs.h
который содержит функции для реализации клиентов NFS. Реализации для этих функций находятся в nfs.c
который скомпилирован для создания 1 из 2 библиотек:
libnfs.a
nfs.rel
Оба необходимы для построения. В качестве части нашего кода мы используем функцию nfsInit(...
который объявлен в librtemsNfs.h
и определяется в nfs.c
,
Так что ошибка довольно очевидна. Когда мы строим, мы получаем ошибку компоновщика:
D:\Git\nfs_stuff\Src\RTEMS_proj/init/srvinit.cpp:453: undefined reference to `nfsInit(int, int)'
collect2: ld returned 1 exit status
Чтобы связать их, мы попробовали несколько способов. У нас есть makefile
но чтобы сделать это проще для всех, я покажу, что выходит из сборки командной строки. Мы попробовали:
powerpc-rtems4.9-g ++ -g -W -g -mcpu = 603e -mstrict-align -meabi -msdata -fno-common … -MANY_PREPROCESSOR_ARGUMENTS … -MANY_INCLUDE_FILES … Map =. / exe / srvevp. map -lc -lm —gc-section -lnfs -mcpu = 603e -mstrict-align -meabi … -MANY_OBJECT_FILES … ./exe/obj/srvinit.o … -MANY_MORE_OBJECT_FILES
Наша команда компиляции и ссылки имеет -lnfs
, перед включением в файл оскорбительного объекта (srvinit.o
). Но мы все равно получаем ошибку компоновщика.
.a
а также .rel
файл. Мы сделали это, добавив: /c/rtems-4.9/powerpc-rtems4.9/5200/lib/libnfs.a /c/rtems-4.9/powerpc-rtems4.9/5200/lib/nfs.rel
в командной строке. Мы добавили его как до, так и после испорченного объектного файла. Мы также попробовали с -L
команда для принудительного связывания по пути. Все это приводит к одной и той же ошибке. Это сложно описать, но при удалении прямой ссылки libnfs.a
Файл мы теряем возможность создавать даже без непосредственного использования NFS. то есть. внутренние файлы RTEMS не могут ссылаться друг на друга. Это очень странно, мне кажется, вам нужно только -lnfs
для построения параметров командной строки, но даже без этого флага он собирается успешно. Без прямого включения мы получаем ошибку:
c:/rtems-4.9/powerpc-rtems4.9/5200/lib\librtemscpu.a(libshell_a-main_mount_nfs.o): In function `rtems_shell_nfs_mounter':
e:\CCNET\rtems-4.9\Trunk\build_5200\powerpc-rtems4.9\c\adept_5200\cpukit\libmisc/../../../../../../rtems-4.9.2/c/src/../../cpukit/libmisc/shell/main_mount_nfs.c:46: undefined reference to `rpcUdpInit'
e:\CCNET\rtems-4.9\Trunk\build_5200\powerpc-rtems4.9\c\5200\cpukit\libmisc/../../../../../../rtems-4.9.2/c/src/../../cpukit/libmisc/shell/main_mount_nfs.c:51: undefined reference to `nfsInit'
e:\CCNET\rtems-4.9\Trunk\build_5200\powerpc-rtems4.9\c\5200\cpukit\libmisc/../../../../../../rtems-4.9.2/c/src/../../cpukit/libmisc/shell/main_mount_nfs.c:58: undefined reference to `nfsMount'
collect2: ld returned 1 exit status
Какой код оболочки rtems не удалось связать. Если мы добавим /c/rtems-4.9/powerpc-rtems4.9/5200/lib/libnfs.a /c/rtems-4.9/powerpc-rtems4.9/5200/lib/nfs.rel
до конца строки сборки, тогда все успешно.
Чтобы повторить, чтобы построить функции командной строки, вам нужно напрямую включить NFS .a
а также .rel
файлы, вам не нужно использовать -lnfs
,
Итак, первый и самый очевидный вопрос: почему это не ссылки, даже если я явно дать файлы библиотеки? Я думаю об этом, возможно, файлы не содержат определения функций, которые я пытаюсь использовать. Но это дискредитировано в другом разделе информации, так как мне нужно, чтобы они связали функции самой ОС RTEMS.
Я знаю, что будет также трудно дать прямой ответ, так как он будет очень невоспроизводим без ПК, всего компилятора и т. Д. Как я могу проверить, что файлы lib содержат определения для моих функций и связаны в правильном порядке? Компилятор специфичен для BSP GCC
Компилятор стилей, предоставляемый RTEMS для Power PC 5200. Он принимает большинство опций компилятора, которые может принять GCC / G ++ 4.2.
В заключение, Есть ли хорошие методы для отладки такой проблемы компоновщика?.
Чтобы сделать весь библиотечный API доступным для вашего кода C ++, вы можете включить сам заголовок библиотеки в внешний блок «C», например:
extern "C" {
#include <librtemsNfs.h>
}
Более подробная информация о том, почему это необходимо, хорошо освещена здесь: Зачем нам экстерн "С"{ #включают <foo.h> } в C ++?
Код библиотеки RTEMS 4.9.2 не готов к связыванию с компилятором C ++, поэтому он имеет другой ABI.
Вам нужно изменить librtemsNfs.h, чтобы использовать блок extern «C» {} для определений библиотеки.
Или, если вы не хотите изменять исходный код RTEMS, объявите эти функции непосредственно в своем коде следующим образом:
extern "C" {
int rpcUdpInit(void);
int nfsInit(int smallPoolDepth, int bigPoolDepth);
int nfsMount(char *uidhost, char *path, char *mntpoint);
}