为什么将参数传递给 g++ 的顺序很重要

2022-01-23 00:00:00 g++ c++

最近,我试图构建一个应用程序,它使用一些库,以共享对象文件的形式提供.我在编译 CPP 代码上浪费了很多时间,但它没有工作.

Recently, I was trying to build an application, which uses some libraries, available in form of shared object files. I wasted lot of time in compiling the CPP code and it didn't work.

下面是命令,之前我是在编译代码-

Below is the command, previously I was trying to compile the code-

g++ -I/opt/ros/indigo/include/ -I/usr/include/eigen3/ -L/opt/ros/indigo/lib/ -lorocos-kdl -lkdl_parser test.cpp -o test

上面的命令总是显示很多undefined references 错误.只是为了好奇,我改变了参数的顺序.以下是正在运行的命令 -

The above command always shows many undefined references errors. Just for the curiosity, I changed the order of parameters. Below is the command, which is working-

g++ -L/opt/ros/indigo/lib -I/opt/ros/indigo/include -I/usr/include/eigen3 test.cpp -lorocos-kdl -lkdl_parser -o test

我在这里发布了完整的代码和解决方案.

I posted the complete code and solution here.

我的问题是为什么将参数传递给 g++ 的顺序很重要?以后有没有办法避免此类问题?

My question is why does the order of passing parameters to g++ matter? Is there any alternative to avoid such problems in future?

推荐答案

一般来说参数的顺序无关紧要,当然也有例外.例如,如果您提供多个 -O 标志,它将是最后一个使用的标志,其他标志相同.

Generally the order of arguments doesn't matter, but there are of course exceptions. For example if you provide multiple -O flags it will be the last one that is used, the same for other flags.

不过,图书馆有点不同,因为对它们来说,顺序很重要.如果目标文件或库 A 依赖于库 B,则 A 在命令行上必须位于 B 之前.这是因为链接器如何扫描符号:当您使用库时,链接器将检查是否有任何可以解析的符号.扫描结束后,该库将被丢弃,不再被搜索.

Libraries are a little different though, because for them the order is significant. If object file or library A depends on library B, then A must come before B on the command line. This is because of how the linker scans for symbols: When you use a library the linker will check if there are any symbols that could be resolved. Once this scan is over the library is discarded and will not be searched again.

这意味着当您拥有 -lorocos-kdl -lkdl_parser test.cpp 时,链接器将首先扫描库 orocos-kdlkdl_parser,请注意这些库没有依赖关系,不需要库中的符号,并继续使用源文件生成的目标文件.

This means when you have -lorocos-kdl -lkdl_parser test.cpp the linker will scan the libraries orocos-kdl and kdl_parser first, notice that there aren't dependencies on these library, no symbols from the libraries are needed, and continue with the object file generated by the source file.

当您将顺序更改为 test.cpp -lorocos-kdl -lkdl_parser 时,链接器将能够解析 test.cpp 引用的未定义符号去图书馆.

When you change the order to test.cpp -lorocos-kdl -lkdl_parser the linker will be able to resolve the undefined symbols referenced by test.cpp when it comes to the libraries.

相关文章