g ++ / clang ++中带有makefile的参数顺序

时间:2013-03-22 12:04:01

标签: c++ g++ makefile ld clang++

在Ubuntu 12.04上使用CERN的ROOT时,我偶然发现了这个非常烦人的问题,但我认为这是一个更普遍的问题。

我有一些带有外部引用的C ++代码,我使用以下makefile编译和链接。在我的Mac OS X 10.8和服务器SL5上运行正常。

CXX=clang++
CXXFLAGS=-Wall -O2 -g $(shell root-config --cflags --libs)

testroot: testroot.cc

评估为

clang++ -Wall -O2 -g -pthread -m64 -I/opt/ROOT/5.34.05/include/root -L/opt/ROOT/5.34.05/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic    testroot.cc   -o testroot

这给了我Ubuntu服务器上未定义的引用和链接器错误。我已经尝试在LDFLAGS中设置libs,但它会产生相同的结果。当我手动编译它并将源文件和-o选项放在库之前时,它编译没有问题。

从其他线程,我认为命令的顺序可能很重要,但我想知道为什么它在某些机器上运行而在其他机器上却没有。即使订单很重要,我认为make足够聪明,可以自行解决。

现在的问题是:我怎样才能解决这个问题?我是否必须使用不同版本的make或ld?我是否必须修改我的makefile?

提前致谢!

3 个答案:

答案 0 :(得分:5)

您不应向-l添加LDFLAGS个参数(甚至不提CXXFLAGS)。对于链接库的正确变量,LDLIBS就像你的makefile中的implicit make rules一样。

在某些机器上,顺序无关紧要,因为GNU ld仅对静态库或启用了--as-needed选项很重要(在某些系统中默认启用)。

答案 1 :(得分:2)

您不应该合并root-config的选项。这应该 是:

CXXFLAGS = -Wall -O2 -g $(shell root-config --cflags)
LIBS     = $(shell root-config -libs -glibs)

然后在适当的时候使用这些选项。 (例如,你 在编译时不会使用$(LIBS),而不是链接。)

至于为什么它适用于不同的系统?不同的系统 有不同的连接器,它们的工作方式不同。也许 一些人不需要额外的库 系统 - 虽然它肯定违背传统, 在现代系统上放置并不一定是不合理的 libc.so中的所有内容。

最后:make如何解决这一问题。使 字面上对你执行的命令一无所知;他们是 只是它传递给shell的字符串。

答案 2 :(得分:0)

您遇到的问题与ld用于解析外部引用的算法有关。您可以尝试不同的ld,但重新排序库列表也可以提供帮助。首先放置基础库(没有依赖关系的那个),然后是依赖于已经列出的库的库,依此类推。