2

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

我有一些带有外部引用的 C++ 代码,我使用以下 makefile 编译和链接这些代码。在我的带有 OS X 10.8 的 Mac 和带有 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但它会产生相同的结果。当我手动编译它并将源文件和 -o 选项放在库之前时,它编译没有问题。

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

现在的问题是:我该如何解决这个问题?我必须使用不同版本的 make 或 ld 吗?我必须修改我的makefile吗?

提前致谢!

4

3 回答 3

5

你不应该添加-l参数LDFLAGS(甚至不提CXXFLAGS)。链接库的正确变量是在makefile中的隐式 make 规则LDLIBS的情况下。

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

于 2013-03-22T12:16:14.503 回答
2

您不应该组合root-config. 它应该是:

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

然后,您可以在适当的情况下使用这些选项。(例如,您不会$(LIBS)在仅编译而不是链接时使用。)

至于为什么它在不同的系统上工作?不同的系统有不同的链接器,它们的工作方式不同。或者,某些系统可能不需要额外的库——尽管它非常违反传统,但在现代系统中将所有内容放入libc.so.

最后:怎么能make解决这个问题。Make 从字面上对您执行的命令一无所知;它们只是传递给外壳的字符串。

于 2013-03-22T12:20:15.060 回答
0

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

于 2013-03-22T12:19:33.023 回答