繁体   English   中英

使用`ld`链接时出现“未定义的符号引用”错误

[英]“undefined reference to symbol” error when using `ld` to link

我是在Linux上编写程序的新手。 我有一个单独的模块程序,它使用shm_openftruncatemmapforkwait 我用gcc -c编译了这个程序,然后用ld -lrt链接它( shm_open需要librt),我得到一个奇怪的链接器错误:

undefined reference to symbol 'waitpid@@GLIBC_2.2.5'

wait的联机帮助页说

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
   waitid():
       Since glibc 2.26: _XOPEN_SOURCE >= 500 ||
           _POSIX_C_SOURCE >= 200809L
       Glibc 2.25 and earlier:
           _XOPEN_SOURCE

但是将#define _XOPEN_SOURCE放在代码中并没有帮助,如果我这样做的话

gcc -c -D _XOPEN_SOURCE 

编译器说ftruncate的隐式声明。

我在VMWare下运行Ubuntu。 GCC是版本gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609

可能有什么不对?

我用gcc -c编译了这个程序,然后用ld -lrt链接它

在你更有经验之前,你不应该试图直接调用ld 相反,使用gcc (或cc )命令链接您的程序以及编译它们。 对于您的用例,命令行如下:

gcc -o myprogram myprogram.o -lrt

应该管用。 (注的位置-lrt ;在大多数情况下, -l选项需要在命令行中,为乏味的历史原因在目标文件去了。)

在引擎盖下,当您使用gcc命令链接程序时,它会为您运行ld ,但它包含一大堆其他参数。 这些都是构建正常程序所需要的,而且它们非常复杂,以至于普通程序员不必担心它们。 其中一个额外的参数是-lc ,告诉ld包含C运行时库的核心,它提供了链接中缺少的waitpid@@GLIBC_2.2.5的定义。 (不要只是尝试在ld命令行上粘贴-lc 。实际上,请尝试一下。你会发现你只会得到一个更神秘的错误信息,可能就像warning: cannot find entry symbol _start一样warning: cannot find entry symbol _startundefined reference to __bswapsi2或谁知道。)

通过在上面的gcc调用中添加-v ,你可以看到所有这些额外参数是什么,如果你很好奇,但它是一个很大的混乱,只有编译器开发人员需要担心它的大部分。

为什么它是gcc命令而不是知道所有这些额外参数的ld命令,你需要正确链接正常程序? 这主要是历史,但这个想法是, ld是最小的,所以如果你正在做一些不寻常的(如链接操作系统内核),你不需要打开任何正常关闭 ,你只需要从零开始,建立。 但是,对于普通程序,人们可以使用(g)cc ,而不必担心额外的争论。

顺便提一下,你在手册中找到的关于_XOPEN_SOURCE的东西不是关于如何在链接时wait ; 它是关于如何在编译时使wait 声明可用。 此外,您定义_XOPEN_SOURCE的值很重要。 将它定义为-D_XOPEN_SOURCE而不是-D_XOPEN_SOURCE=500就是为什么你抱怨ftruncate的隐式声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM