近期项目中用到了一些C++开源库,使用g++编译的时候出现了一些问题,在此做个小结。
项目中用到的库:STL(这个是废话了),occi,log4c,tinyxml
- occi
1. 下载oracle instant client以下3个包: basic.zip, sdk.zip, sqlplus.zip并解压
2. 建立/u01/app/oracle/product/11.1.0/db_1文件夹路径并拷贝上一步解压的文件到此目录下
3. 设置环境变量,编辑.bash_profile,添加以下代码:
export ORACLE_HOME=/u01/app/oracle/product/11.1.0/db_1 export TNS_ADMIN=$ORACLE_HOME/network/admin export LD_LIBRARY_PATH=$ORACLE_HOME export SQLPATH=$ORACLE_HOME PATH=$PATH:$HOME/bin:$ORACLE_HOME
4. 在$ORACLE_HOME下建立network/admin路径, 并新建tnsnames.ora文件,添加以下代码:
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/11.1.0/db_1/admin/tnsnames.ora # Generated by Oracle configuration tools. ORCL = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.16.36.63)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = ORCL) ) )
5. 在$ORACLE_HOME下建立libclntsh.so.11.1和libocci.so.11.1的软连接
ln -s libclntsh.so.11.1 libclntsh.so ln -s libocci.so.11.1 libocci.so
6. 修改makefile文件中的include和lib路径,比如:
ORACLE_INCLUDES=-I$(ORACLE_HOME)/sdk/include INC=$(ORACLE_INCLUDES) ORACLE_LIBS=-L$(ORACLE_HOME) LIB=$(ORACLE_LIBS) -lclntsh -locci
将$(INC)加入到-I参数中,将$(LIB)加入到-L参数中
7. make, done.
- log4c
1. 解压log4c-1.2.1.tar.gz到/usr/local/src目录下
2. 进入log4c-1.2.1目录, 运行./configure --prefix=/usr
3. make & make install
注意:如果不指定安装目录(即默认指向/usr/local),安装完成后需要将/usr/local/lib添加到环境变量LD_LIBRARY_PATH中
- tinyxml
这个是最简单的,解压tinyxml_2_6_1.zip,将tinyxml的六个源文件直接拷贝到工程目录下即可。
这些配置都是在虚拟机Red Hat Enterprise Linux Workstation 6.1下完成的,但到了服务器部署的时候又出现了问题,服务器上仅配置了occi环境,于是正常使用动态链接库的程序在服务器上无法正常编译,提示缺少动态库,当然可以选择在服务器上安装配置log4c环境,但是计算机组的同事显然不情愿这样,这种情况有如下4种解决方案(欢迎补充):
1. 编辑~/.bash_profile或/etc/profile(全局),添加liblog4c.so文件所在路径到LD_LIBRARY_PATH中:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib;export LD_LIBRARY_PATH
2. 编辑/etc/ld.so.conf(适用于除/lib和/usr/lib以外),添加liblog4c.so文件所在路径:
/usr/local/lib
或者bash下直接:
echo "/usr/local/lib" >> /etc/ld.so.conf
运行ldconfig以刷新ld.so.cache(需要root权限)
3. log4c安装后会同时生成liblog4c.a静态库文件,拷贝此文件到工程目录,修改makefile:
# The pre-processor and compiler options. MY_CFLAGS = -I$(ORACLE_HOME)/rdbms/public \ # -I/usr/include # The linker options. MY_LIBS = ./liblog4c.a -L$(ORACLE_HOME)/lib \ # -L/usr/lib # The pre-processor options used by the cpp (man cpp for more). CPPFLAGS = -Wall # The options used in linking as well as in any direct use of ld. LDFLAGS = -lclntsh -locci \ # -llog4c
ld会将liblog4c.a链接到可执行文件中,生成的可执行文件在删除liblog4c.a的情况下仍可以运行。
4. 链接时加入-R参数(或-rpath)指定运行时动态库位置,拷贝liblog4c.so文件到工程目录,修改makefile:
# The pre-processor and compiler options. MY_CFLAGS = -I$(ORACLE_HOME)/rdbms/public \ # -I/usr/include # The linker options. MY_LIBS = -L. -L$(ORACLE_HOME)/lib \ # -L/usr/lib # The pre-processor options used by the cpp (man cpp for more). CPPFLAGS = -Wall -Wl,-R.:/usr/local/lib #CPPFLAGS = -Wall -Wl,-rpath=.:/usr/local/lib # The options used in linking as well as in any direct use of ld. LDFLAGS = -lclntsh -locci \ -llog4c
g++编译时可以通过-Wl参数调用链接程序ld,-Wl,表示后面的参数将传给ld,例如:-Wl,-rpath
最后一种方法应该是最好的解决方案,最后总结一下Linux动态链接库的搜索顺序:
1. 链接时指定的搜索路径
2. LD_LIBRARY_PATH环境变量
3. /etc/ld.so.conf中的路径
4. 默认动态库路径/lib
5. 默认动态库路径/usr/lib