编译篇

较大型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

待续

05-11 18:19