c++ - 为什么库链接器标志有时必须在最后使用 GCC?

标签 c++ c linux makefile posix

我正在编写一个使用 librt 的小型 C 程序。如果我将链接标志放在开头而不是结尾,程序将无法编译,这让我感到非常惊讶:

目前,要编译我所做的程序:

gcc -o prog prog.c -lrt -std=gnu99

如果我要执行以下操作,它将无法在 librt 中找到函数:

gcc -std=gnu99 -lrt -o prog prog.c

然而,这适用于其他库。我在尝试使用简单的 Makefile 时发现了这个问题。 make 实际上编译 prog.c 而不是先喜欢(使用 -c 标志),然后进行链接。

这是 Makefile:

CC = gcc

CFLAGS = -std=gnu99

LIBS= -lrt

LDFLAGS := -lrt


prog: prog.o

        $(CC) -o prog prog.c -lrt -std=gnu99

我在输入 make 时得到的输出是:

gcc -std=gnu99   -c -o prog.o prog.c
gcc -lrt  prog.o   -o prog
prog.o: In function `main':
prog.c:(.text+0xe6): undefined reference to `clock_gettime'
prog.c:(.text+0x2fc): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [buff] Error 1

我现在已经制作了一个将链接放在 gcc 行末尾的 Makefile,但是我很困惑为什么如果链接标志在开头它不起作用。

如果有人可以向我解释这一点,我将不胜感激。谢谢。

最佳答案

当链接器处理每个模块(无论是库还是目标文件)时,它会尝试解析每个 undefined symbol ,同时可能会添加到其 undefined symbol 列表中。当它到达模块列表的末尾时,它要么解析了所有 undefined symbol 并成功,要么报告了 undefined symbol 。

在您的情况下,当它处理 librt 时,它没有 undefined symbol 。处理过程导致clock_gettime 是一个 undefined symbol 。 gcc 不会返回并在 librt 中查找 undefined symbol 。

因此,您应该始终将代码放在首位,然后是库,然后是平台提供的库。

希望这会有所帮助。

关于c++ - 为什么库链接器标志有时必须在最后使用 GCC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9417169/

相关文章:

c - 错误使用execlp函数

c - 结构的两个 malloc 定义之间的区别

linux - 如何清除 Docker 任务历史记录

linux - Shell脚本不从输入文件中获取参数

c++ - 请先实例化 QApplication 对象

C++, float 到整数类型转换

c++ - 在 C++ 类中使用按引用传递和成员初始化列表时会发生什么?

python - 在 Python virtualenv 中导入自己的 C 模块

C++ 前向声明和 'Incomplete type is not allowed' 错误

linux - Fedora 中的 OpenSceneGraph