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

Ser*_*off 4 c glibc undefined-reference

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

undefined reference to symbol 'waitpid@@GLIBC_2.2.5'
Run Code Online (Sandbox Code Playgroud)

该联机帮助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
Run Code Online (Sandbox Code Playgroud)

#define _XOPEN_SOURCE如果我这样做,那么输入代码就无济于事了

gcc -c -D _XOPEN_SOURCE 
Run Code Online (Sandbox Code Playgroud)

编译器说隐式声明ftruncate.

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

可能有什么不对?

zwo*_*wol 6

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

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

gcc -o myprogram myprogram.o -lrt
Run Code Online (Sandbox Code Playgroud)

应该管用.(注的布局-lrt;在大多数情况下,-l选择需要进入在命令行中,为乏味的历史原因的目标文件.)

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

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

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

顺便提一下,你在手册中找到的东西_XOPEN_SOURCE不是关于如何wait在链接时提供的; 它是关于如何使申报wait可在编译时间.此外,您定义的值很_XOPEN_SOURCE重要.定义它-D_XOPEN_SOURCE而不是-D_XOPEN_SOURCE=500为什么你得到关于隐含声明的投诉ftruncate.