动态库的生成有多种方式:
(1)直接通过编译源文件通过目标文件用g++或者gcc指令生成动态库;
(2)通过将已有的静态库打散后再打包也可以生成动态库;
(3)通过链接已有的静态库生成动态库;
利弊分析:
(2),(3)需要有现成的静态库;(2)打散,打包的过程简单,但是静态库有多个模块,不同模块有可能存在同名文件,打散之后就会导致接口丢失(一个子模块A.o 覆盖另外一个子模块A.o),另外静态库是链接的符号是调用过程中覆盖到的,打散重新链接就会出现超级多的未定义以及C++重载导致的C中找不到符号等等问题;另外(3)是一种比较快捷的方式,通常要另外写一个源文件主函数要调用静态库的入口函数且必须保证入口能调到静态库中需要的所有功能模块,这样在使用动态库时发现有些功能没有链接进去。
目前还是采取标准套路:
利用编译生成的目标文件和需要链接的系统库,porting库生成动态库。
基本命令:
(1) gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
(2)通过复杂一点的makefile调用,输入需要生成的动态库名称,依赖的库,所有 .o 文件即可。
Compile.rules文件如下:
LINK:= $(CROSS)-g++
export CROSS:=arm-linux-androideabi
define MMCP_SHARED_LIBRARY
$(LINK) -nostdlib \
-Wl,-shared,-Bsymbolic \
-Wl,-soname,$(notdir $@)\
-Wl,--start-group \
$(Bestwin_Hi3716C_Static_Lib) \
-ldl -llog -lz -lutils -lcutils -lnetutils -lporting \
$(LDFLAGS) \
$(INPUTSSO) \
$^\
-Wl,--end-group \
-Wl,--whole-archive -Wl,--no-whole-archive \
-Wl,--no-undefined -Wl,-z,noexecstack \
-Wl,-Map=$@.map\
-o $@; \
cp -rfv $@ $@_notstrip;\
$(CROSS)-strip -S $@;
CCompile.rules文件如下:
$(DLL_EXPORT): $(OBJECTS_C) $(OBJECTS_CXX) $(INPUTS)
@echo Building $@
$(MMCP_SHARED_LIBRARY)
说明OBJECTS_C,OBJECTS_CXX分别是c,c++文件的目标文件传到Compile.rules中就是依赖文件 $^ ,
而DLL_EXPORT则是在模块目录先makefile定义动态库名称 传到Compile.rules就是$@,
模块目录下的makefile
include CCompile.rules
include Compile.rules
定义 DLL_EXPORT ,SOURCES,INPUTSOSO即可。
下一篇将直接用一个脚本配置makefile来完成这项任务。