在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?
提前致谢!
答案 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,但重新排序库列表也可以提供帮助。首先放置基础库(没有依赖关系的那个),然后是依赖于已经列出的库的库,依此类推。