对“nfsInit”的未定义引用
Undefined reference to `nfsInit`
我目前正在尝试将 NFS 服务器集成到POWER PC 5200
上运行RTEMS 4.9.2
的一些代码中。这将很难简洁地解释,所以请耐心等待。
RTEMS NFS
目前,RTEMS 通过 nfs.c 文件实现 NFS 客户端。为了激活命令行界面并能够使用mount -t nfs ...
选项,您需要将#define CONFIGURE_SHELL_MOUNT_NFS
添加到配置文件中,并将rtems nfs文件与-lnfs
链接。有关更多详细信息,请参阅此处。正确执行此操作使我们能够实现 RTEMS nfs 客户端,并且我们可以从命令行挂载远程驱动器。
直接使用 RTEMS NFS 客户端
我们不会在程序中公开 RTEMS 命令行,因此我们希望能够直接使用 nfs 接口。RTEMS 库提供了包含实现 nfs 客户端函数的librtemsNfs.h
。这些函数的实现在nfs.c
中,编译为创建 2 个库中的 1 个:
-
libnfs.a
-
nfs.rel
两者都需要构建。作为我们代码的一部分,我们使用函数 nfsInit(...
该函数在 librtemsNfs.h
中声明并在 nfs.c
中定义。
错误
所以错误很明显。当我们构建时,我们得到链接器错误:
D:Gitnfs_stuffSrcRTEMS_proj/init/srvinit.cpp:453: undefined reference to `nfsInit(int, int)'
collect2: ld returned 1 exit status
尝试链接这些库
为了将这些链接起来,我们尝试了多种方法。我们有一个makefile
但为了让每个人都更容易,我将展示命令行构建中出现的内容。我们尝试过:
- 推荐的方法是与 -lnfs(源 - 一个老问题(链接,这样做会产生一个漂亮而复杂的构建命令:
powerpc-rtems4.9-g++ -g -wall -g -mcpu=603e -mstrict-align -meabi -msdata -fno-common ... -MANY_PREPROCESSOR_ARGUMENTS ... -MANY_INCLUDE_FILES ...Map=./exe/srvevp.map -lc -lm --gc-sections -lnfs -mcpu=603e -mstrict-align -meabi ... -MANY_OBJECT_FILES ... ./exe/obj/srvinit.o ... -MANY_MORE_OBJECT_FILES
我们的编译和链接命令在包含有问题的目标文件(srvinit.o
(之前-lnfs
。但是我们仍然收到链接器错误。
- 我尝试按路径直接链接到
.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/liblibrtemscpu.a(libshell_a-main_mount_nfs.o): In function `rtems_shell_nfs_mounter':
e:CCNETrtems-4.9Trunkbuild_5200powerpc-rtems4.9cadept_5200cpukitlibmisc/../../../../../../rtems-4.9.2/c/src/../../cpukit/libmisc/shell/main_mount_nfs.c:46: undefined reference to `rpcUdpInit'
e:CCNETrtems-4.9Trunkbuild_5200powerpc-rtems4.9c5200cpukitlibmisc/../../../../../../rtems-4.9.2/c/src/../../cpukit/libmisc/shell/main_mount_nfs.c:51: undefined reference to `nfsInit'
e:CCNETrtems-4.9Trunkbuild_5200powerpc-rtems4.9c5200cpukitlibmisc/../../../../../../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 操作系统本身的功能。
我知道这也很难给出直接的答案,因为如果没有安装PC和所有编译器等,它将是非常不可重现的。 如何检查 lib 文件是否包含函数的定义以及是否以正确的顺序链接?该编译器是 RTEMS 为 Power PC 5200 提供的 BSP 特定GCC
样式编译器。它接受GCC/G++ 4.2可以接受的大多数编译器选项。
最后,是否有任何好的方法来调试这样的链接器问题?
为了使整个库 API 可用于您的C++代码,您可以将库标头本身包含在外部"C"块中,如下所示:
extern "C" {
#include <librtemsNfs.h>
}
关于为什么需要这样做的更多细节在这里有很好的介绍:为什么我们需要 extern "C"{ #include
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);
}
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 对 Scalar ::Scalar() 的未定义引用
- 对复制 CTOR 和 CTOR 的未定义引用
- 对显式实例化的模板函数的未定义引用
- TensorRT (C++ API) 对"createNvOnnxParser_INTERNAL"的未定义引用
- 2个模板化类的非模板友元函数未定义引用错误
- 编译 libfluid 样本控制器时对"event_base_del_virtual"的未定义引用
- 获取对function_name的未定义引用
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 对结构方法的未定义引用
- 使用内联函数 c++ 的未定义引用
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 对 DLOPEN 的未定义引用
- QT C++中对全局变量的未定义引用
- 快速数学导致对"__pow_finite"的未定义引用
- 对 boost::system::d etail::system_category_instance 的未定义引用,从
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用