"undefined reference to symbol" 使用 `ld` 到 link 时出错
"undefined reference to symbol" error when using `ld` to link
我是在 Linux 上编写程序的新手。我有一个使用 shm_open
、ftruncate
、mmap
、fork
和 wait
的单个模块程序。我用 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
.
有什么问题吗?
I compiled this program with gcc -c
and then linked it with ld -lrt
除非您更有经验,否则不应尝试直接调用 ld
。相反,link 您的程序,以及使用 gcc
(或 cc
)命令编译它们。对于您的用例,命令行如下:
gcc -o myprogram myprogram.o -lrt
应该可以。 (请注意 -lrt
的位置;在大多数情况下,由于乏味的历史原因,-l
选项需要在命令行上 之后 目标文件。)
在后台,当您 link 使用 gcc
命令的程序时,它会为您运行 ld
,但它包含 一大堆 的附加参数。这些都是构造普通程序所必需的,而且它们足够复杂,普通程序员不必担心它们。额外的参数之一是 -lc
,告诉 ld
包含 C 运行时库的核心,它提供了 link 中缺少的 waitpid@@GLIBC_2.2.5
的定义。 (不要只是尝试自己在 ld
命令行上粘贴 -lc
。实际上,请尝试一下。您会发现您只会收到更神秘的错误消息,可能类似于 warning: cannot find entry symbol _start
或 undefined reference to __bswapsi2
或者谁知道。)
如果你好奇的话,你可以通过在上面的 gcc
调用中添加一个 -v
来查看所有这些额外的参数是什么,但这是一团糟,只有编译器开发人员需要担心大部分。
为什么 gcc
命令而不是 ld
命令知道所有这些额外的参数,你需要正确地 link 一个正常的程序?它主要是历史的,但想法是 ld
是最小的,所以如果你正在做一些不寻常的事情(例如 linking 操作系统内核)你不需要把任何东西变成正常的 off,你只需要从零开始,不断积累。但是,对于普通程序,人们可以使用 (g)cc
而不必担心额外的参数。
顺便说一下,您在手册中找到的关于 _XOPEN_SOURCE
的内容并不是关于如何在 link 时间使 wait
可用;它是关于如何使 wait
的 声明 在 编译 时可用。此外,您定义的值 _XOPEN_SOURCE
很重要。将其定义为 -D_XOPEN_SOURCE
而不是 -D_XOPEN_SOURCE=500
是您收到有关 ftruncate
.
隐式声明的投诉的原因
我是在 Linux 上编写程序的新手。我有一个使用 shm_open
、ftruncate
、mmap
、fork
和 wait
的单个模块程序。我用 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
.
有什么问题吗?
I compiled this program with
gcc -c
and then linked it withld -lrt
除非您更有经验,否则不应尝试直接调用 ld
。相反,link 您的程序,以及使用 gcc
(或 cc
)命令编译它们。对于您的用例,命令行如下:
gcc -o myprogram myprogram.o -lrt
应该可以。 (请注意 -lrt
的位置;在大多数情况下,由于乏味的历史原因,-l
选项需要在命令行上 之后 目标文件。)
在后台,当您 link 使用 gcc
命令的程序时,它会为您运行 ld
,但它包含 一大堆 的附加参数。这些都是构造普通程序所必需的,而且它们足够复杂,普通程序员不必担心它们。额外的参数之一是 -lc
,告诉 ld
包含 C 运行时库的核心,它提供了 link 中缺少的 waitpid@@GLIBC_2.2.5
的定义。 (不要只是尝试自己在 ld
命令行上粘贴 -lc
。实际上,请尝试一下。您会发现您只会收到更神秘的错误消息,可能类似于 warning: cannot find entry symbol _start
或 undefined reference to __bswapsi2
或者谁知道。)
如果你好奇的话,你可以通过在上面的 gcc
调用中添加一个 -v
来查看所有这些额外的参数是什么,但这是一团糟,只有编译器开发人员需要担心大部分。
为什么 gcc
命令而不是 ld
命令知道所有这些额外的参数,你需要正确地 link 一个正常的程序?它主要是历史的,但想法是 ld
是最小的,所以如果你正在做一些不寻常的事情(例如 linking 操作系统内核)你不需要把任何东西变成正常的 off,你只需要从零开始,不断积累。但是,对于普通程序,人们可以使用 (g)cc
而不必担心额外的参数。
顺便说一下,您在手册中找到的关于 _XOPEN_SOURCE
的内容并不是关于如何在 link 时间使 wait
可用;它是关于如何使 wait
的 声明 在 编译 时可用。此外,您定义的值 _XOPEN_SOURCE
很重要。将其定义为 -D_XOPEN_SOURCE
而不是 -D_XOPEN_SOURCE=500
是您收到有关 ftruncate
.