使用 gcc 链接库:参数顺序
当我将 Ubuntu 发行版升级到 11.10 后,我开始看到 gcc 的奇怪链接器行为。我能够通过将 -l
参数移动到 gcc 命令的末尾来解决该问题(我的问题与 这个帖子,以及建议的解决方案对我有用......谢谢!)。
我的问题是...为什么我现在才出现这个问题?我在 OS X 和 Ubuntu 上开发和测试这段代码已经有一段时间了:我从来不知道 -l
命令应该在你的 .c 文件之后,但即便如此,这从来没有给我带来任何好处。之前出现的问题。我猜这与 GCC 版本的关系比 Ubuntu 发行版本的关系更大。
这个新版本是否只是比早期版本更严格地执行此要求?
As soon as I upgraded my Ubuntu distro to 11.10, I started seeing strange linker behavior with gcc. I was able to fix the problem by moving my -l
arguments to the end of the gcc command (my problem was similar to the one described in this thread, and the proposed solution worked for me...thanks!).
My question is...why did I have this problem only now? I've been developing and testing this code on OS X and Ubuntu for a while: I never knew that -l
commands are supposed to go after your .c files, but even so, this never gave me problems before. I'm guessing it has more to do with the version of GCC than the Ubuntu release version.
Is this newer version simply enforcing this requirement more strictly than earlier versions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于 gcc 以及其他编译器(例如 clang),链接器命令参数的顺序确实很重要。
根据经验,在编写链接器命令时,我将使用以下顺序:
共享库的顺序也很重要。如果 libfoo.so 依赖于 libbar.so,则应在
-lbar
之前列出-lfoo
。如果您不知道确切的依赖关系,这可能会变得非常复杂。 Linux 上的以下命令可能会有所帮助:
这会列出 libfoo.so 所依赖的所有共享库。
至于你的问题为什么你的特定 gcc 版本会出现这个问题,在不知道你的应用程序需要哪些库的情况下很难判断。但如果您应用我上面描述的顺序,它应该适用于较旧和较新的 gcc 版本。
提示:如果使用正确,CMake 可以为您处理所有依赖项...
With gcc but also other compilers (e.g. clang), the order of linker command arguments does matter.
As a rule of thumb, I would use the following order when composing the linker command:
The order of shared libraries does matter as well. If libfoo.so depends on libbar.so, you should list
-lfoo
before-lbar
.This can get quite complex if you don't know the exact dependencies. The following command on linux could help:
This lists all shared libs on which libfoo.so depends.
As to your question why this problem popped up with your particular gcc version, it's hard to tell without knowing which libs your application requires. But if you apply the order like I described above, it should work for both older and newer gcc versions.
Hint: CMake, if used correctly, can handle all that dependency stuff for you...
我怀疑你的问题是因为 Ubuntu v11.10 的 GCC v4.6 默认启用了
-Wl,--as-needed
,这使得链接器对命令行上库的顺序敏感。Ubuntu v11.10 包含 GCC v4.6 作为默认编译器 [1]。
Ubuntu v11.10 的 GCC 默认启用
-Wl,--as-needed
[2]。“--as-needed 选项还使链接器对命令行上库的顺序敏感。您可能需要稍后在命令行中移动一些库,因此它们位于其他库或文件之后需要他们的符号。” [3]
[1] https://wiki.ubuntu.com/OneiricOcelot/ReleaseNotes# GCC_4.6_工具链
[2] https://wiki.ubuntu.com/ToolChain/CompilerFlags#A -Wl.2C--按需
[3] https://wiki.ubuntu.com/NattyNarwhal/ToolchainTransition
I suspect your problem was because Ubuntu v11.10's GCC v4.6 enabled
-Wl,--as-needed
by default, and that made the linker sensitive to the ordering of libraries on the command line.Ubuntu v11.10 included GCC v4.6 as the default compiler [1].
Ubuntu v11.10's GCC enabled
-Wl,--as-needed
by default [2]."The --as-needed option also makes the linker sensitive to the ordering of libraries on the command-line. You may need to move some libraries later in the command-line, so they come after other libraries or files that require symbols from them." [3]
[1] https://wiki.ubuntu.com/OneiricOcelot/ReleaseNotes#GCC_4.6_Toolchain
[2] https://wiki.ubuntu.com/ToolChain/CompilerFlags#A-Wl.2C--as-needed
[3] https://wiki.ubuntu.com/NattyNarwhal/ToolchainTransition