g++/clang++中参数的顺序与makefile
Order of parameters in g++/clang++ with makefile
我在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
中设置lib,但它产生相同的结果。当我手动编译它并将源文件和-o选项放在库之前时,它可以正常编译。
从其他线程,我认为命令的顺序可能很重要,但我想知道为什么它在一些机器上,而在其他机器上没有。即使顺序很重要,我认为make
足够聪明,可以自己弄清楚。
现在的问题是:我怎样才能绕过这个?我必须使用不同版本的make或old吗?我必须修改我的makefile吗?
提前感谢!
不应该给LDFLAGS
添加-l
参数(甚至不应该提到CXXFLAGS
)。对于像makefile中那样的隐式make规则,链接库的适当变量是LDLIBS
。
在某些机器上,顺序无关紧要,因为在GNU中,它只对静态库或启用了--as-needed
选项(在某些系统上默认启用)有影响。
您不应该将root-config
的选项组合。它应该是:
CXXFLAGS = -Wall -O2 -g $(shell root-config --cflags)
LIBS = $(shell root-config -libs -glibs)
然后在适当的地方使用这些选项。(例如,你在编译时不使用$(LIBS)
,而不是链接。)
至于为什么它在不同的系统上工作?不同的系统有不同的链接器,工作方式也不同。或者有些程序不需要额外的库虽然这绝对是违反传统的,这在现代系统中并不一定是不合理的一切在libc.so
。
最后:make
是怎么弄明白这些的?使完全不知道您执行的命令;他们就是传递给shell的字符串
您遇到的问题与用于解决外部引用的算法有关。您可以尝试不同的方法,但是重新排序库列表也会有所帮助。把基本库放在第一位(没有依赖关系的那个),然后是依赖于已经列出的库的库,依此类推。
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 数到第n个楼梯的路(顺序无关紧要)
- 优先顺序:智能指针和类析构函数
- 在循环中按顺序遍历成员变量
- 独立读取-修改-写入顺序
- QML按钮点击功能执行顺序
- C++中数据类型修饰符的顺序
- 当比特(而不是字节)的顺序至关重要时的持久性
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 通过选项卡的文本设置QTabWidget顺序
- c++11评估顺序(未定义的行为)
- 如何在C++中递归地按相反顺序打印集合
- 给定顺序中的事件处理
- 具有包含其他对象的类的对象创建顺序
- 针对遗留库的链接:来自预制makefile的-lgfortranbegin
- C++Makefile编译顺序
- g++/clang++中参数的顺序与makefile