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

时间:2019-02-09 22:19:56

标签: c glibc undefined-reference

我是刚开始在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版。

怎么了?

1 个答案:

答案 0 :(得分:6)

  

我用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的定义。 (不要只是自己尝试将-lc粘贴在ld命令行上。实际上,请尝试一下。您会发现您只会得到更神秘的错误消息,可能类似于{{1 }}或warning: cannot find entry symbol _start或什至知道的人。)

如果您好奇的话,可以通过在上面的undefined reference to __bswapsi2调用中添加-v来查看所有这些额外的参数是什么,但这很麻烦,只有编译器开发人员才需要担心大部分。

为什么gcc命令而不是gcc命令知道正确链接普通程序所需的所有这些额外参数?它主要是历史性的,但是想法是ld很小,因此,如果您做一些不寻常的事情(例如,链接操作系统内核),则无需关闭任何正常的 ,您只需要从零开始就可以建立。但是,对于普通程序,人们可以使用ld,而不必担心额外的参数。

顺便说一句,您在手册中找到的关于(g)cc的内容与在链接时如何使_XOPEN_SOURCE无关。这是关于如何在 compile 时使wait声明可用的。同样,您定义wait的值也很重要。将其定义为_XOPEN_SOURCE而不是-D_XOPEN_SOURCE的原因就是您抱怨隐式声明-D_XOPEN_SOURCE=500