问题描述
我是刚开始在Linux上编写程序.我有一个使用 shm_open
, ftruncate
, mmap
, fork
和 wait
.我用 gcc -c
编译了该程序,然后将其与 ld -lrt
链接( shm_open
需要librt),但得到了一个奇怪的链接器错误:
I am new to writing programs on Linux. I have a single module program that uses shm_open
, ftruncate
, mmap
, fork
, and wait
. I compiled this program with gcc -c
and then linked it with ld -lrt
(librt is needed for shm_open
) and I got a strange linker error:
undefined reference to symbol 'waitpid@@GLIBC_2.2.5'
等待
的手册页上说
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
放入代码中无济于事,如果可以的话
but putting #define _XOPEN_SOURCE
in the code doesn't help, and if I do
gcc -c -D _XOPEN_SOURCE
编译器说 ftruncate
的隐式声明.
我正在VMWare下运行Ubuntu.GCC是 gcc版本(Ubuntu 5.4.0-6ubuntu1〜16.04.11)5.4.0 20160609
.
I am running Ubuntu under VMWare. GCC is version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
.
有什么问题吗?
推荐答案
除非您经验丰富,否则不要尝试直接调用 ld
.而是使用 gcc
(或 cc
)命令链接程序并进行编译.对于您的用例,使用如下命令行:
Until you are much more experienced, you should not attempt to invoke ld
directly. Instead, link your programs, as well as compiling them, using the gcc
(or cc
) command. For your use case, a command line like this:
gcc -o myprogram myprogram.o -lrt
应该工作.(请注意 -lrt
的位置;在大多数情况下, -l 选项需要放在命令行中的 之后,以免乏味历史原因.)
should work. (Note the placement of the -lrt
; in most cases, -l
options need to go after object files on the command line, for tedious historical reasons.)
在后台,当您使用 gcc
命令链接程序时,该程序将为您运行 ld
,但其中包含一个整堆其他参数.这些都是构造普通程序所必需的,而且它们非常复杂,以至于普通程序员不必担心它们.额外的参数之一是 -lc
,它告诉 ld
包括C运行时库的核心,该库提供了 waitpid @@ GLIBC_2.2.5
在您的链接中丢失.(不要只是自己尝试将 -lc
粘贴在 ld
命令行上.实际上,请尝试一下.您会发现,您只会得到更加神秘的错误消息,可能类似于 warning:找不到条目符号_start
或对__bswapsi2
的未定义引用,甚至找不到.)
Under the hood, when you link a program using the gcc
command, it runs ld
for you, but it includes a whole bunch of additional arguments. These are all needed to construct normal programs, and they're complicated enough that normal programmers shouldn't have to worry about them. One of the extra arguments is -lc
, telling ld
to include the core of the C runtime library, which provides the definition of waitpid@@GLIBC_2.2.5
that was missing from your link. (Don't just try sticking -lc
on the ld
command line yourself. Actually, do try it. You'll discover that you only get an even more mysterious error message, probably something like warning: cannot find entry symbol _start
or undefined reference to __bswapsi2
or who even knows.)
如果您好奇的话,可以通过在上面的 gcc
调用中添加 -v
来查看所有这些额外的参数,但这很麻烦.只有编译器开发人员才需要担心其中的大部分问题.
You can see what all those extra arguments are, if you're curious, by adding a -v
to the above gcc
invocation, but it's a big mess and only compiler developers need to worry about most of it.
为什么为什么 gcc
命令而不是 ld
命令知道正确链接普通程序所需的所有这些额外参数?这主要是历史性的,但是我们的想法是 ld
很小,因此,如果您做一些不寻常的事情(例如,链接操作系统内核),则无需关闭任何正常的 off ,您只需要从零开始进行构建即可.但是,对于普通程序,人们可以使用(g)cc
,而不必担心额外的参数.
Why is it the gcc
command and not the ld
command that knows all these extra arguments you need to link a normal program correctly? It's mostly historical, but the idea is that ld
is minimal, so if you're doing something unusual (e.g. linking an operating system kernel) you don't need to turn anything normal off, you just need to start from zero and build up. But, for normal programs, people can use (g)cc
and not have to worry about the extra arguments.
顺便说一句,您在手册中找到的关于 _XOPEN_SOURCE
的内容与在链接时如何使 wait
可用无关;这是关于如何在 compile 时使 wait
的声明可用的.另外,您定义 _XOPEN_SOURCE
的值很重要.将其定义为 -D_XOPEN_SOURCE
而不是 -D_XOPEN_SOURCE = 500
就是为什么您抱怨 ftruncate
的隐式声明的原因.
Incidentally, the stuff you found in the manual about _XOPEN_SOURCE
is not about how to make wait
available at link time; it's about how to make the declaration of wait
available at compile time. Also, the value you define _XOPEN_SOURCE
to matters. Defining it as -D_XOPEN_SOURCE
rather than -D_XOPEN_SOURCE=500
is why you got a complaint about an implicit declaration of ftruncate
.
这篇关于“对符号的未定义引用";使用ld链接时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!