小编典典

为什么有时必须使用GCC在库链接器标志的末尾添加标记?

linux

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

此刻,我要编译程序:

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

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

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

但是,这可以与其他库一起使用。我在尝试使用简单的Makefile时发现了问题。进行实际编译的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

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

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


阅读 296

收藏
2020-06-02

共1个答案

小编典典

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

就您而言,当它处理librt时,它没有未定义的符号。处理过程导致clock_gettime是未定义的符号。gcc不会返回并在librt中查找未定义的符号。

因此,您应该始终先获取代码,再获取库,再获取平台提供的库。

希望这可以帮助。

2020-06-02