makefile + shell脚本自动生成动态库

makefile

SUB_DIR = module1 module2 module3 module4 ... 

all: target1  target2  share_lib

share_lib:
    @for dir in $(SUB_DIR); do \
		echo ------------------------compiling $$dir------------------------; \
		$(MAKE) -C $$dir; \
	done
    . generate_share_lib.sh
备注:makefile主要通过循环完成子模块的编译,生成目标文件,然后启动脚本。


generate_share_lib.sh脚本如下:

#!/bin/sh
###############################################
######        全局变量的声明             ######
###############################################
export EXPORTNAME=libmmcp_product
export libsufix=a
export sosufix=so

#链接库的路径
export ANDROIDLIBPATH=${MMCP_HOME}/linkLibrary/androidlib/${REAL_MMCP_PLATFORM}
export MY_WORK_PATH=${MMCP_HOME}/lib/${PLATFORM}/${MMCP_COMPILING_MODE}
export INPUTS_PATH=${android_gcc_dir}/lib/gcc/arm-linux-androideabi/4.4.3

#链接库
export INPUTSGCC=${ANDROIDLIBPATH}/libgcc.a
export INPUTSSUPCPLUS=${ANDROIDLIBPATH}/libsupc++.a
export INPUTSSUPCPLUSPIC=${ANDROIDLIBPATH}/libstdc++_pic.a
export THIRDPARTY_LIB=${ANDROIDLIBPATH}/thirdlib
export BINDER_SERVER_LIB=${MMCP_HOME}/linkLibrary/binder/${REAL_MMCP_PLATFORM}/libBinderManager_UDRM_provider.a
export GRAPH_LIB=${MMCP_HOME}/graph/fontengine/arphic_standard/${MMCP_PLATFORM}/libarphic_standard.${libsufix}

#跳转到工作目录下
cd ${MY_WORK_PATH}

pwd;

echo $@

cd ${MMCP_HOME}
#将编译生成的个模块.o 拷贝到${MY_WORK_PATH}下对应的模块里面
for module_name in $@
do
	mkdir -p ${MY_WORK_PATH}/${module_name}
	chmod 777 ${MY_WORK_PATH}/${module_name} -Rf
	echo "===========> copy all .o to <=======" ${module_name}
#	dir_arr=$(find ${module_name}/  -name ${PLATFORM};)
#	for dir in ${dir_arr[*]}
#	do
#		find $dir -name "*.o"  |xargs -i cp {} ${MY_WORK_PATH}/${module_name}/ -v
#	done
	find ${module_name}/ -name "*.o" |grep -E "${PLATFORM}/" |grep -E "${MMCP_COMPILING_MODE}/" |xargs -i cp {} ${MY_WORK_PATH}/${module_name}/ -v
done



#打包目录
cd ${MY_WORK_PATH}

export sub_dir=$(find ./ -type d ;)
export OBJECT_O=$(find ${sub_dir}/ -name "*.o";)

pwd;
echo "\n=======> tar *.o to  *.so <====== \n" 

arm-linux-androideabi-g++ -v -Wl,--start-group -nostdlib -Wl,-shared,-Bsymbolic -fPIC -Wl,--whole-archive \
	-L${ANDROIDLIBPATH}/ \
	-lporting -ldl -llog -lz -lutils -lcutils -lnetutils -ldvm -lbinder	-lcs_BootLoader -lc -lm 
	${INPUTS_PATH}/crtbeginT.o \
	${INPUTS_PATH}/crtend.o \
	${INPUTS_PATH}/crtendS.o \
	${OBJECT_O}
	${INPUTSGCC} \
	${INPUTSSUPCPLUS} \
	${BINDER_SERVER_LIB} \
	${GRAPH_LIB} \
	-Wl,--no-whole-archive	\
	${INPUTSSUPCPLUSPIC} \
	-Wl,--end-group -Wl,-soname -Wl,${EXPORTNAME}.${sosufix} -o ${EXPORTNAME}.${sosufix}

cd ${MMCP_HOME}

mkdir -p out/${PLATFORM}/${MMCP_COMPILING_MODE}
cp -v ${MMCP_HOME}/lib/${PLATFORM}/${MMCP_COMPILING_MODE}/${EXPORTNAME}.${sosufix} ${MMCP_HOME}/integration/product/OTT_DVB/porting/Android_6A801/coship/lib/androidlib
cp -v ${MMCP_HOME}/lib/${PLATFORM}/${MMCP_COMPILING_MODE}/${EXPORTNAME}.${sosufix} ${MMCP_HOME}/out/${PLATFORM}/${MMCP_COMPILING_MODE}
rm -rvf  ${MY_WORK_PATH}/${EXPORTNAME}.${sosufix}

#删除创建的临时文件夹
cd ${MY_WORK_PATH}
find ./ -type d|grep -vw "./" |xargs -i rm {} -rf
cd -


备注:由于脚本本身没有makefile本身自带的一些系统函数,脚本中多处使用到了linux 下的find命令组合grep命令来完成查找指定文件的功能

例如,删除当前文件下的子文件夹

find ./ -type d|grep -vw "./" |xargs -i rm {} -rf

或 find ./ -type d -exec rm {}


附上git grep "str" 查找指令使用:https://www.kernel.org/pub/software/scm/git/docs/git-grep.html


一般ls -l 查看文件夹下详细信息时,会发现有一个./目录,可以用grep 的 -v (过滤掉),-w (全字匹配)来去掉不需要删除的部分,另外 xargs -i 相当于find的 -exec

选项后面可以添加命令做响应的操作,又如:

find ./ -name *.o |grep -w "PLATFORM_NAME" |xargs -i nm {} -A |grep SymbolName/FunctionName 查看某个符号在某个平台的哪个文件中出现


此处nm有别于strings命令,strings只显示出处,没有标明用处,nm可以查看到出现符号的具体属性。

find ./ -name *.a |grep -w "PLATFORM_NAME" |xargs -i nm {} -A |grep -w "T SymbolName/FunctionName" 查看某个符号在某个平台的哪个静态库中定义


当生成动态库DlibA.so 时,链接了某一个静态库A,但是没有调用静态库的接口functionA,而接口生成动态库DlibB.so 时链接DlibA.so,DlibB.so中要使用接口

functionA,此时会出现找不到而链接不过的问题。

此问题是由于静态库中接口没有直接调用,链接时会丢掉,可以通过ar -x 的方式打散静态库将.o文件链接进去,另外一种方法是直接在生动动态库时调用一下

需要的接口。第二种方法也是通过线程静态库生成动态库的一个捷径。


你可能感兴趣的:(shell,grep,动态库,Makfile,find指令用法)