为什么库链接器标志有时不得不在最后使用GCC?

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

目前,我编译的程序是:

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

如果我要做下面的事情,它将无法在librt中find函数:

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 

inputmake时输出的结果是:

 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,但是我很疑惑为什么在链接标志处于开始状态时它不起作用。

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

Solutions Collecting From Web of "为什么库链接器标志有时不得不在最后使用GCC?"

当链接器处理每个模块(无论是一个库还是一个目标文件)时,它会尝试解析每个未定义的符号,同时可能会添加到未定义的符号列表中。 当它到达模块列表时,它或者已经解析了所有未定义的符号,并且成功或者报告了未定义的符号。

在你的情况下,当它处理librt时,它没有未定义的符号。 处理过程导致clock_gettime是一个未定义的符号。 gcc不会回头查看librt中未定义的符号。

出于这个原因,你应该总是有你的代码,其次是你的图书馆,其次是平台提供的图书馆。

希望这可以帮助。

ld (GNU链接器)文档( http://sourceware.org/binutils/docs/ld/Options.html#Options ):

链接器只会在命令行中指定的位置搜索一次存档。 如果存档定义了一个符号,该符号在命令行上存档之前出现的某个对象中未定义,则链接器将从存档中包含相应的文件。 但是,稍后在命令行中出现的对象中的未定义符号将不会导致链接器再次搜索存档。

所以,如果你指定的库太早,链接器将扫描它,但没有找到任何有趣的东西。 然后链接器移动到由编译器生成的目标文件,并找到需要解析的引用,但已经扫描了该库,不会再费心去查看那里。