动态build log4c库

需求是这样的:

要写一个公用的C库libtoken,该库会被多个C/C++模块使用,但是由于这些模块是在不同的环境下build的,比如CentOS 5.3、CentOS 6.3、64bit、32bit……,因此不方便做成一个.so或.a文件放那儿,让这些模块直接取做link,因为那是会出问题滴!所以,让每个模块在build之前,先在和自己模块相同的环境下build libtoken库,把build出来的库文件以及库的头文件放到自己的源文件路径下,再去build自己的模块。

同时libtoken要通过log4c库写log,这就导致log4c库也不能直接放一个.a或.so到libtoken库的路径下。


解决办法:

将log4c的源代码放到libtoken库的路径下,修改libtoken库的Makefile,使得build libtoken库之前会先build 和install log4c库,将build出来的liblog4c.a和log4c的头文件通过make install的方式,拷贝到libtoken路径下,最后再build libtoken库。


简单示例:

假设我们写一个使用log4c的log4c-tetst工程,目录结构如下。log4c-1.2.4是下载的log4c源码,vendors/log4c是要放置log4c库文件和头文件的地方。

log4c-test
>main.cpp
>Makefile
>log4c-1.2.4
>vendors
>>log4c

Makefile

LOG4C_DIR = ./log4c-1.2.4
LOG4C_VENDOR_DIR = ./vendors/log4c
LOG4C_VENDOR_INCLUDE_DIR = $(LOG4C_VENDOR_DIR)/include
LOG4C_VENDOR_LIB_DIR = $(LOG4C_VENDOR_DIR)/lib
TARGET = ./test

all: build-log4c
	g++ main.cpp -o $(TARGET) -I$(LOG4C_VENDOR_INCLUDE_DIR) $(LOG4C_VENDOR_LIB_DIR)/liblog4c.a -lexpat

build-log4c:
	cd $(LOG4C_DIR) && ./configure --prefix=`pwd`/../vendors/log4c && make && make install

clean:
	rm $(TARGET) -f
	cd $(LOG4C_DIR) && make uninstall

执行make之后的目录结构:

log4c-test
>main.cpp
>Makefile
>log4c-1.2.4
>vendors
>>log4c
>>>bin
>>>etc
>>>include
>>>lib
>>>share

其中,liblog4c.a就在lib中,我们要的头文件就在include中。


注意:

1)log4c源码build出来的文件都在log4c源码的 src/log4c/.libs 隐藏文件夹下。这里我要的只是其中的liblog4c.a。

2)Makefile中g++ main.cpp一行中,最后有个貌似多余的"-lexpat",如果没有它,make时会出现下面的错误。原因(参考)是,默认情况下,log4c库依赖于expat做log4crc xml文件解析,并且log4c库要放在其他链接的库的前面。(可以加上--without-expat选项,不使用expat库而使用log4c自定义的解析器

g++ main.cpp -o ./test -I./vendors/log4c/include ./vendors/log4c/lib/liblog4c.a
./vendors/log4c/lib/liblog4c.a(domnode-expat.o): In function `sd_domnode_read':
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:316: undefined reference to `XML_ParserCreate'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:321: undefined reference to `XML_SetStartElementHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:322: undefined reference to `XML_SetEndElementHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:323: undefined reference to `XML_SetCharacterDataHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:324: undefined reference to `XML_SetCommentHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:325: undefined reference to `XML_SetUserData'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:327: undefined reference to `XML_Parse'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:355: undefined reference to `XML_ParserFree'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:328: undefined reference to `XML_GetCurrentByteIndex'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:328: undefined reference to `XML_GetCurrentColumnNumber'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:328: undefined reference to `XML_GetCurrentLineNumber'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:328: undefined reference to `XML_GetErrorCode'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:328: undefined reference to `XML_ErrorString'
./vendors/log4c/lib/liblog4c.a(domnode-expat.o): In function `sd_domnode_fread':
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:242: undefined reference to `XML_ParserCreate'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:247: undefined reference to `XML_SetStartElementHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:248: undefined reference to `XML_SetEndElementHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:249: undefined reference to `XML_SetCharacterDataHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:250: undefined reference to `XML_SetCommentHandler'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:251: undefined reference to `XML_SetUserData'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:258: undefined reference to `XML_GetBuffer'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:268: undefined reference to `XML_ParseBuffer'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:301: undefined reference to `XML_ParserFree'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:269: undefined reference to `XML_GetCurrentByteIndex'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:269: undefined reference to `XML_GetCurrentColumnNumber'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:269: undefined reference to `XML_GetCurrentLineNumber'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:269: undefined reference to `XML_GetErrorCode'
/home/yasi/log4c-test/log4c-1.2.4/src/sd/domnode-expat.c:269: undefined reference to `XML_ErrorString'
collect2: ld returned 1 exit status
make: *** [all] Error 1

3)Makefile中,cd $(LOG4C_DIR)一行中,如果用 LOG4C_VENDOR_DIR 代替 `pwd`/../vendors/log4c,则会得到错误提示“不要使用相对路径”。如果把这一行和LOG4C_VENDOR_DIR定义换成下面两句,则虽然没有“不要使用相对路径”的错误提示,但是,其实这里的LOG4C_VENDOR_DIR 的值已经不是我们想要的路径了,因为之前执行了 cd $(LOG4C_DIR) 的动作,`pwd`得到的已经不是log4c-test工程的根目录了,而是log4c-test工程的根目录下的 log4c-1.2.4 子目录,于是make install 把文件都拷贝到了 log4c-1.2.4/vendors/log4c 下面!

LOG4C_VENDOR_DIR = `pwd`/vendors/log4c
cd $(LOG4C_DIR) && ./configure --prefix=$(LOG4C_VENDOR_DIR) && make && make install

4)当然也可以只make而不make install,只要指定正确的log4c include和log4c lib路径就可以了,其实这样貌似还简单些~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值