首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么库链接器的旗帜有时必须在结尾使用GCC?

为什么库链接器的旗帜有时必须在结尾使用GCC?
EN

Stack Overflow用户
提问于 2012-02-24 00:36:08
回答 2查看 6.7K关注 0票数 24

我正在写一个小的C程序,它使用了函数库。我很惊讶,如果我把链接标志放在开头而不是结尾,程序就不能编译:

目前,为了编译这个程序,我这样做:

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

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

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

然而,这适用于其他库。我在尝试使用一个简单的Makefile时发现了这个问题。首先在没有make的情况下编译成实际的程序(使用-c标志),然后进行链接。

这是Makefile:

代码语言:javascript
运行
复制
CC = gcc

CFLAGS = -std=gnu99

LIBS= -lrt

LDFLAGS := -lrt


prog: prog.o

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

当我输入make时得到的输出将是:

代码语言:javascript
运行
复制
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行的末尾,但是我很困惑,如果链接标志在开头,它为什么不起作用。

如果有人能给我解释一下,我将不胜感激。谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-24 00:44:05

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

在您的例子中,当它处理librt时,它没有未定义的符号。处理过程导致clock_gettime是一个未定义的符号。gcc不会回过头去库中寻找那些未定义的符号。

因此,您应该始终先准备好代码,然后是库,最后才是平台提供的库。

希望这能有所帮助。

票数 28
EN

Stack Overflow用户

发布于 2012-02-24 00:45:59

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

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

因此,如果您过早地指定库,链接器将扫描它,但找不到任何感兴趣的东西。然后,链接器转到编译器生成的目标文件,并找到需要解析的引用,但它已经扫描了库,不会再去那里查找。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9417169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档