为什么我必须在链接器行的末尾传递库?

pul*_*lse 0 c c++ linker makefile

像这样的命令将起作用:

(LD) $(LDFLAGS) -o reip.app newlib/crt0.o reip.o renetif.o fs.o httpd.o liblwip.a newlib/libc.a
Run Code Online (Sandbox Code Playgroud)

但是如果我在*.o文件之前放置*.a - 它将无法从libs中找到函数.

我搜索了一些旧的项目,发现在makefile文件中,如下所示:

$(CC)  $(LIBS) -o $(TARGET) JukeboxMain.o JukeboxPlayer.o ...
Run Code Online (Sandbox Code Playgroud)

直到我将$(LIBS)移到行尾才能工作.但我记得很久以前这对我很有用.有人可以回答改变了什么以及为什么它不再起作用了)PS我不喜欢玩编译器,链接器和其他工具 - 我更喜欢创建一些东西;)

Mad*_*ist 5

我不能回答你为什么认为它可能以前有用过.但我可以告诉你为什么它一般不起作用.大多数POSIX样式的链接器,包括ld在GNU/Linux和其他设备上使用的GNU binutils ,都是单通道链接器.

这意味着他们从开始到结束一次遍历命令行中列出的元素,并且它们不会返回.当链接器启动时,它基本上寻找一个符号,main.当它遍历命令行时,foo.o链接器找到的任何目标文件()总是被添加到可执行文件中.该对象提供了一个已定义的符号列表,以及一个未定义的列表(需要从其他对象获得).

当链接器访问静态库(libfoo.a)时,它会查看该库中的目标文件,如果对象包含链接器所需的任何符号,则会将该对象添加到可执行文件中.如果它不包含链接器所需的任何符号,则会跳过该对象.

在命令行的末尾,如果需要任何符号但未找到,则链接失败.

所以,你可以看到,为了确保一次性找到所有内容,需要来自库的符号的东西必须提供这些符号的库之前,或者当链接器在其单次传递中击中库时,它赢了不知道库是否需要并且会跳过它们.