编译篇
较大型cpp项目的代码组织、编译都是深耦合的。
一般提供一个总体的makefile,进入各个模块,又有自己的makefile,这些makefile又都依赖于一些被include的文件的的定义,为什么要这样原因不必多言。
但要想改变编译环境时,却很难顺利的移植。我们可能踩过的坑有:
1)找不到类库,这个还比较好处理,绝对是你指定的目录问题,甚至是当前目录——一个小圆点不要疏忽了
2)依赖库不匹配,比如glibc、i686、x86_64等,只管去匹配好了
3)还是找不到定义: 注意调整依赖的顺序,一般越是通用、没有耦合的库要尽可能放在后面,让前面找不到定义的库有机会去查找,还有就是双向关联的类——做好声明。
如何定位一些原因,必须学会如下命令:
- ldd -r
- strings | grep [...]
- file 或者 objdump -a
- nm --demangle
- readelf -s [YOURBINNAME]
- objectdump -a *.a
- strings *.so | grep [...]
搞清楚各个库的版本,尤其是libc的
可以用(ldd --version 查看glibc的版本,如ldd (GNU libc) 2.12; 命令/lib64/libc.so.6也可以)
这里再补充些网上找来的资源:
编译源代码时,链接的时候查找顺序是:
(1) -L 指定的路径, 从左到右依次查找
(2) 由环境变量 LIBRARY_PATH 指定的路径,使用":"分割从左到右依次查找
(3) /etc/ld.so.conf 指定的路径顺序
(4) /lib 和 /usr/lib (64位下是/lib64和/usr/lib64)
动态库调用的查找顺序:
(1) ld的-rpath参数指定的路径, 这是写死在代码中的
(2) ld脚本指定的路径
(3) LD_LIBRARY_PATH 指定的路径
(4) /etc/ld.so.conf 指定的路径
(5)/lib和/usr/lib(64位下是/lib64和/usr/lib64)
一般情况链接的时候我们采用-L的方式指定查找路径, 调用动态链接库的时候采用LD_LIBRARY_PATH的方式指定链接路径。
另外注意一个问题,就是只要查找到第一个就会返回,后面的不会再查找.
makefile中对操作系统的判断:
ARCH = $(shell getconf LONG_BIT)
uname -m
ifeq ($(OS_TYPE), x86_64) LIB_EPOLL =
else LIB_EPOLL = -lepoll
endif
待续