为什么我必须在链接器行的末尾传递库
Why do I have to pass libraries in the end of linker line?
这样的命令会起作用:
(LD) $(LDFLAGS) -o reip.app newlib/crt0.o reip.o renetif.o fs.o httpd.o liblwip.a newlib/libc.a
但是,如果我把*.a放在*.o文件之前,它将无法从库中找到函数。
我搜索了一些旧项目,在makefiles中发现了这样的行:
$(CC) $(LIBS) -o $(TARGET) JukeboxMain.o JukeboxPlayer.o ...
这也不起作用,直到我把$(LIBS)移到行的末尾。但我记得很久以前它对我有用。有人能回答一下发生了什么变化以及为什么它不再起作用吗?)附言:我不太喜欢玩编译器、链接器和其他工具——我更喜欢创建一些东西;)
我无法回答您为什么认为它以前可能有效。但我可以告诉你为什么它在一般情况下不起作用。大多数POSIX风格的链接器,包括在GNU/Linux和其他平台上使用的GNU binutilsld
,都是单程链接器。
这意味着它们会将命令行中列出的元素从头到尾遍历一次,并且不会返回。当链接器启动时,它基本上是在寻找一个符号main
。在执行命令行时,链接器找到的任何对象文件(foo.o
)都会添加到可执行文件中。该对象提供了一个已定义的符号列表和一个未定义的列表(其他对象需要)。
当链接器访问静态库(libfoo.a
)时,它会查看该库中的对象文件,如果某个对象包含链接器需要的任何符号,它会将该对象添加到可执行文件中。如果它不包含链接器所需的任何符号,则将跳过该对象。
在命令行的末尾,如果需要任何符号但未找到,则链接将失败。
因此,您可以看到,为了确保在一次遍历中找到所有内容,库中需要符号的东西必须在提供这些符号的库之前,否则,当链接器在一次访问中访问库时,它将不知道需要这些库,并将跳过它们。
相关文章:
- 你能检查一下为什么在这个代码中从链接列表中删除项目不起作用吗
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 为什么开关的优化方式与 c/c++ 中的链接不同?
- 为什么我的链接器在找到Coin4d.lib后搜索Coin4sd.lib?
- 为什么我们不编写可以处理C++标识符的汇编器和链接器?
- 为什么每当我尝试运行此链接列表删除功能时都会收到分段错误错误?
- 为什么我会收到链接器错误:未定义对 ..?
- 为什么调用没有正文的纯虚拟方法不会导致链接器错误?
- 为什么在使用 SDL2 时仍然收到'undefined reference'链接器错误?
- 为什么我们需要在链接列表链接之前填写数据?
- 为什么当我在 C 程序中链接静态库时会"undefined symbol"?
- 为什么C++可执行文件在与较新的libstdc++.so链接时运行得更快?
- 使用 CMake 与其他静态库链接的静态库 - 一个有效,一个无效。为什么?
- C++ 为什么在定义的编译和链接之前引用外部实例的程序
- 为什么只有一个库的链接器错误'multiple definitions'?在 Android Studio 中使用 CMake (3.4.1)
- 使用Cygwin C++时出现未定义的引用错误,为什么我的文件没有链接?
- 链接二进制库或共享库时,为什么必须传入我依赖的共享库?
- C++ 为什么要级联共享对象链接
- 为什么链接器报告全局函数的乘法定义符号,而不是类静态方法
- 为什么当我从语句检查中删除"+ mod"时,以下程序给出错误的答案。问题链接:https://www.codechef.com/problems/FFC219B