在编译动态库时,要求我们要去编写jni/Android.mk文件,告诉编译器编译出来的库时应包含包含编译文件和其他引用库。但对于一个大项目来说,维护这个文件肯定是一件比较繁琐的事情,因为每加一个文件或减一个文件等就要改下Android.mk来重新生成打包文件。所以很有必要对这个文件进行自动化处理,就是在绝大部分的情况下都不需要修改此文件。
由于我没有从cocos2d-x引擎中自带的那些Android.mk找到好的例子,就在网上搜索makefile的编写技巧。终于找到了较好的解决方案。
在本利中的Classes的文件结构如下
1. 首先在Android.mk中加入以下代码
#遍历出Classes下所有的cpp和c文件,也遍历出jni/hellocpp下所有的cpp文件
define walk
$(subst jni/, ,$(wildcard $(2)/*.cpp) $(filter %.cpp %.c, $(wildcard $(1)) $(foreach v, $(wildcard $(1)/*), $(call walk, $(v)))))
endef
#将上面遍历出的文件列表赋给CPP_FILES
CPP_FILES := $(call walk, $(LOCAL_PATH)/../../Classes, $(LOCAL_PATH)/hellocpp)
LOCAL_SRC_FILES := $(CPP_FILES)
#打印测试
$(warning $(LOCAL_SRC_FILES))
打印出来的内容如下
可见LOCAL_SRC_FILES的值是我们所需要的
如果项目中的头文件不是以相对目录引入的话还要对LOCAL_C_INCLUDES进行修改
继续在Android.mk中加入以下代码
ALL_DIR :=
#获取Classes下的所有文件夹(如果一个文件夹下有两个文件的话则FILES_DIR出现两个重复的文件夹名)
FILES_DIR := $(dir $(filter ../../%, $(LOCAL_SRC_FILES)))
#去掉FILES_DIR中的重复文件夹名,此时的FILES_DIR的每个文件夹名的最后面会多出一个/
$(foreach n, $(FILES_DIR), $(if $(filter $(n), $(ALL_DIR)), , $(eval ALL_DIR += $(n))))
#给FILES_DIR的每个文件夹名的后面加上一/
C_INCLUDES := $(foreach m, $(ALL_DIR), $(LOCAL_PATH)/$(m)/)
#去掉FILES_DIR的每隔文件夹名的//( 因为上面在每个文件夹名的最后面多加了一个/ 所以要去掉//)
C_INCLUDES := $(subst //,,$(C_INCLUDES))
LOCAL_C_INCLUDES := $(C_INCLUDES)
#打印测试
$(warning $(LOCAL_C_INCLUDES))
打印出来的内容如下
可见LOCAL_C_INCLUDES的值是我们所需要的
这样就不用怎么每次编译就要去修改Android.mk文件了
(ps: 之前也写过一篇关于自动生成LOCAL_SRC_FILES的python脚本,虽然这个会带来一点点方便,但远没有达到理想的效果,故删之)