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

时间:2016-11-15 06:38:59

标签: c++ g++

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

以下是命令,之前我正在尝试编译代码 -

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错误。只是为了好奇,我改变了参数的顺序。下面是命令,它正在工作 -

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

我发布了完整的代码和解决方案here

我的问题是为什么将参数传递给g ++的顺序很重要?有没有其他方法可以避免将来出现这类问题?

2 个答案:

答案 0 :(得分:9)

一般来说,参数的顺序并不重要,但当然有例外。例如,如果您提供多个-O标志,它将是最后一个使用的标志,对于其他标志也是如此。

但是,图书馆有点不同,因为对他们而言,订单很重要。如果对象文件或库A依赖于库B,那么A必须在命令行上B之前。这是因为链接器扫描符号的方式:当您使用库时,链接器将检查是否存在可以解析的符号。扫描完成后,库将被丢弃,不会再次搜索。

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

当您将订单更改为test.cpp -lorocos-kdl -lkdl_parser时,链接器将能够解析test.cpp引用的未定义符号。

答案 1 :(得分:1)

如果您不想关心订单,您可以(至少在某些版本的gcc中)使用库周围的括号。

请参阅:

Why does the order in which libraries are linked sometimes cause errors in GCC?

具体做法是:

  

如果静态库依赖于另一个库,而另一个库则依赖于另一个库   再取决于前库,有一个循环。你可以解决   这可以通过 - (和 - )括起循环依赖库来实现   as - (-la -lb - )(你可能需要逃避parens,例如 - (和    - ))。然后,链接器会多次搜索这些封闭的lib,以确保解析循环依赖关系。