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文件链接进去,另外一种方法是直接在生动动态库时调用一下
需要的接口。第二种方法也是通过线程静态库生成动态库的一个捷径。