在我的上一篇博文中,讲到如何把Tinyxml 在Linux下编译为静态库,从而使用这个静态库来进行XML编程。但是,如果我想使用动态库来进行XML编程,因为使用动态库生成的可执行文件更小,更节省内存。那么,应该怎么做呢,很简单,只需要修改上一篇博文中的步骤(2)和步骤(4):
步骤(2):将其中的注释为Targets of the build的下一行OUTPUT := xmltest一行修改为:OUTPUT := libtinyxml.so
步骤(4):将其中的注释为Output的下一行的${LD} -o $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS}修改为:在"${LD}"后面加一个参数:-shared用于生成动态库。
接下来,我们就来分析下为什么对Makefile进行上述操作就能生成静态库和动态库,首先,举个例子来看看怎么生成简单的库文件:
以linux下的静态库和动态库为例
静态库:
先将源文件编译成目标文件:gcc -c test.c test1.c
生成静态库:ar -rc libstatic.a test.o test1.o
共享库:
先将源文件编译成目标文件:gcc -c test.c test1.c
生成共享库:gcc -fPIC -shared -o libshared.so test.o test1.o //f后面跟一些编译选项,PIC是其中一种,表示生成位置无关代码(Position Independent Code)一般用在编译动态库的时候
ar命令可以用来建立或修改备存文件,或是从备存文件中抽取文件,详细用途可以到网上查。通过上面的小实例,再加上如果你了解Makefile的规则和使用,那么相信你已经明白为什么要这样修改Makefile了。我把Makefile主要的内容粘贴下来分析:
CC := gcc
CXX := g++
LD := g++
AR := ar rc
RANLIB := ranlib
#****************************************************************************
# Targets of the build
#****************************************************************************
OUTPUT := xmltest
all: ${OUTPUT}
#****************************************************************************
# Source files
#****************************************************************************
SRCS := tinyxml.cpp tinyxmlparser.cpp xmltest.cpp tinyxmlerror.cpp tinystr.cpp
# Add on the sources for libraries
SRCS := ${SRCS}
OBJS := $(addsuffix .o,$(basename ${SRCS}))
#****************************************************************************
# Output
#****************************************************************************
${OUTPUT}: ${OBJS}
${LD} -o $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS}
从上面分析可以看出OUTPUT为最终的目标,因此修改OUTPUT变量的值可以改变最终生成的文件的名字,改为libtinyxml.a则生成的文件名就为libtinyxml.a。而OUTPUT的生成则依赖于OBJS变量,和下面的命令:${LD} -o $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS},由LD := g++可以看出,LD变量为g++命令,因此在${LD}后加上一个-shared选项,就可以生成动态库文件。由AR := ar rc可以看出,AR变量为ar命令,因此把${LD}改为${AR},并且把-o选项删除,就可以生成静态库文件。
现在,通过上面的分析,再加上如果你已经了解Makefile的规则和使用,相信原因应该已经明了。那么,如果我想把Tinyxml移植到嵌入式开发平台下,那么该如何修改Makefile呢,很简单,只需要再把CXX := g++改为CXX :=arm-linux-g++,即把编译器改为交叉编译器。