[转]编写Android.mk中的LOCAL_SRC_FILES的终极技巧
希望看原文的请移步:[原创]编写Android.mk中的LOCAL_SRC_FILES的终极技巧
问题的引入
在使用NDK编译C/C++项目的过程中,免不了要编写Android.mk文件,其中最重要的就是LOCAL_SRC_FILES
源文件列表. 考虑有如下源文件分布的情况:
cpp文件全部位于android项目下的jni文件夹下,结构如下
jni
|---.cpp
|---.cpp
|---Android.mk
|---Application.mk
|---ndk_test.cpp
|---src
| |---core
| | |---core1.cpp
| | |---core2.cpp
| |---src1.cpp
| |---src2.cpp
按照通常的写法,在android.mk
中,应该写入
LOCAL_SRC_FILES := ndk_test.cpp \
1.cpp \
2.cpp \
src/src1.cpp \
src/src2.cpp \
src/core/core1.cpp \
src/core/core2.cpp
繁琐不堪!
初步解法:一句话引入单个目录(不包括子目录)下的所有cpp源文件
继续上面的情况为例,我可以这样写
MY_CPP_LIST := $(wildcard $(LOCAL_PATH)/*.cpp)
MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/src/*.cpp)
MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/src/core/*.cpp) LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%)
问题解决. 简单解释一下上面的几句话
- 1、
MY_CPP_LIST := $(wildcard $(LOCAL_PATH)/*.cpp)
,这句话的意思是使用wildcard函数获取$(LOCAL_PATH)目录也就是jni目录下的所有后缀名为cpp的文件,并把结果放到变量MY_CPP_LIST
里. - 我们知道$(LOCAL_PATH)指的是当前
Android.mk
文件所在目录,所以通过这句话,MY_CPP_LIST
中的值应该是jni/1.cpp jni/2.cpp jni/ndk_test.cpp
. - 2、
MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/src/*.cpp)
, 获取jni/src
目录下的源文件,并追加到变量MY_CPP_LIST
里 - 3、
MY_CPP_LIST += $(wildcard $(LOCAL_PATH)/src/core/*.cpp)
,同上,获取jni/src/core
目录下的源文件 - 4、通过以上几步,得到
MY_CPP_LIST
中内容是:jni/1.cpp jni/2.cpp
jni/ndk_test.cpp
jni/src/src1.cpp
jni/src/src2.cpp
jni/src/core/core1.cpp
jni/src/core/core2.cpp
- 5、
LOCAL_SRC_FILES := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%)
,前面我们获取的文件都是以jni
开头的,而真正编译所需要的文件都应该是直接从jni
目录开始的,所以我们使用模式替换
把所有文件名前面的jni/
去掉.
这里我解释一下
$(MY_CPP_LIST:$(LOCAL_PATH)/%=%)
的语法含义,它的意思是对MY_CPP_LIST
中每一项,应用冒号后面的规则,规则是什么呢?规则是$(LOCAL_PATH)/%=%
,意思是,查找所有$(LOCAL_PATH)/
开头的项,并截取后面部分最后一句话也可以使用subst函数写成:
#替换每一项中的 "$(LOCAL_PATH)/" 为 ""(空)
LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/, , $(MY_CPP_LIST))
或使用patsubst函数写成
#同模式替换,这里使用patsubst函数
LOCAL_SRC_FILES := $(patsubst $(LOCAL_PATH)/%, %, $(MY_CPP_LIST))
具体语法请参考:Functions for String Substitution and Analysis
实际使用中,可以把代码放在jni目录以外的目录里,这时只要修改wildcard函数里的相对路径就可以了,甚至也可以使用绝对路径,只要你愿意.
以上代码已经足以应付大多数情况了,不过人的懒惰是无极限的,像上面的情况我的所有源文件都在jni目录下,为什么还要把每个子目录都写一行呢,不太优雅呀,最好能写一句话把jni目录下的所有源文件都引入.
- 5、
进阶:引入单个目录(包括子目录)下的所有cpp源文件
为了达到引入目录下的所有源文件,包括子目录这个目标,我在
android.mk
中这样写#声明一个变量MY_CPP_PATH表示源码目录
MY_CPP_PATH := $(LOCAL_PATH)/ #获取目录下的所有文件
My_All_Files := $(shell find $(MY_CPP_PATH)/.)
My_All_Files := $(My_All_Files:$(MY_CPP_PATH)/./%=$(MY_CPP_PATH)%) #从My_All_Files中再次提取所有的cpp文件,这里也可以使用filter函数
MY_CPP_LIST := $(foreach c_file,$(My_All_Files), $(wildcard $(c_file)/*.cpp) )
MY_CPP_LIST := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%) LOCAL_SRC_FILES := $(MY_CPP_LIST)通过以上几行,成功得到了jni目录包含它的子目录下的所有cpp源文件,并正确编译.实际使用中,代码不一定存放在jni目录下,修改
MY_CPP_PATH
就可以了,注意:MY_CPP_PATH
最好使用以$(LOCAL_PATH)
开头的相对目录这种写法极大的方便了项目的开发,以前在源码目录下新建cpp源文件,新建目录都不需要再来修改
android.mk
文件了.还有一个问题,上面代码里只是引入cpp文件,如果源码文件夹下还有c文件呢,怎么办?再多写几行?
进阶2.0:引入单个目录(包括子目录)下的所有*.cpp和*.c源文件
这里,我直接给出代码
MY_CPP_PATH := $(LOCAL_PATH)/
My_All_Files := $(shell find $(MY_CPP_PATH)/.)
My_All_Files := $(My_All_Files:$(MY_CPP_PATH)/./%=$(MY_CPP_PATH)%)
MY_CPP_LIST := $(filter %.cpp %.c,$(My_All_Files))
MY_CPP_LIST := $(MY_CPP_LIST:$(LOCAL_PATH)/%=%) LOCAL_SRC_FILES := $(MY_CPP_LIST)代码中用到了filter函数.
还不满足?如果项目的源码有多个目录放在不同的地方,而且有多个后缀,怎么办?
终极进阶:引入多个目录(包括子目录)下的多个后缀名的源文件
上代码(2013年10月9日修正):
# 扫描目录下的所有源文件
MY_FILES_PATH := $(LOCAL_PATH) \
$(LOCAL_PATH)/../../Classes MY_FILES_SUFFIX := %.cpp %.c %.cc My_All_Files := $(foreach src_path,$(MY_FILES_PATH), $(shell find $(src_path) -type f) )
My_All_Files := $(My_All_Files:$(MY_CPP_PATH)/./%=$(MY_CPP_PATH)%)
MY_SRC_LIST := $(filter $(MY_FILES_SUFFIX),$(My_All_Files))
MY_SRC_LIST := $(MY_SRC_LIST:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES := $(MY_SRC_LIST)
以上代码中,变量
MY_FILES_PATH
保存源文件所在目录,MY_FILES_SUFFIX
保存源文件的后缀名
[转]编写Android.mk中的LOCAL_SRC_FILES的终极技巧的更多相关文章
- 编写Android.mk中的LOCAL_SRC_FILES的终极技巧(转)
转自:http://blog.csdn.net/fu_zk/article/details/12836431 问题的引入 在使用NDK编译C/C++项目的过程中,免不了要编写Android.mk文件, ...
- 【转】Update: Android.mk 中的 LOCAL_SRC_FILES, LOCAL_C_INCLUDES
看原文请移步:Update: Android.mk 中的 LOCAL_SRC_FILES, LOCAL_C_INCLUDES 我在先前的两篇post 编写Android.mk中的LOCAL_SRC_F ...
- [转]编写 android.mk 中 LOCAL_C_INCLUDES 的技巧
看原文请移步:编写 android.mk 中 LOCAL_C_INCLUDES 的技巧 在编写android.mk的过程中,免不了要修改LOCAL_C_INCLUDES来设置头文件的include目录 ...
- Android.mk中的经常使用语法
Android.mk编译文件是用来向Android NDK描写叙述你的C,C++源码文件的, 今天查了一些经常使用的的语法. 一 概述: 一个Android.mk文件用来向编译系统描写叙述你的源码. ...
- Android.mk中添加宏定义
在Boardconfig.mk 中添加一个 IS_FLAG := true 由于Boardconfig.mk和各目录的Android.mk是相互关联的 所以我们可以在Android.mk 中添加 一个 ...
- Android.mk中添加宏定义【转】
本文转载自:http://blog.csdn.net/huangyabin001/article/details/38302021 在Boardconfig.mk 中添加一个 IS_FLAG := t ...
- Android.mk 中常用“LOCAL_” 变量
编写模块的编译文件,实际就是定义一系列以“LOCAL_”开头的编译变量,因此我们有必要弄明白这些变量的具体含义.下面是一些经常使用的LOCAL_编译变量的说明: 变量名 说明 LOCAL_ASSET_ ...
- Android.mk中引用第3方动态库
Android.mk 文件内容: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOC ...
- Android.mk中call all-subdir-makefiles和call all-makefiles-under,$(LOCAL_PATH)的区别(转载)
转自:http://blog.csdn.net/jackyu613/article/details/5949324 在写Android.mk文件时,call all-subdir-makefiles和 ...
随机推荐
- java数组转json
public String toJsonObject(String[] list) { String json="["; for (int i=0;i<list.length ...
- POJ 1163 The Triangle DP题解
寻找路径,动态规划法题解. 本题和Leetcode的triangle题目几乎相同一样的,本题要求的是找到最大路径和. 逆向思维.从底往上查找起就能够了. 由于从上往下能够扩展到非常多路径.而从下往上个 ...
- KNOCKOUTJS DOCUMENTATION-绑定(BINDINGS)-自定义绑定
除了ko内建的绑定,还可以自定义绑定,灵活地封装复杂的行为使之可重用. 自定义绑定 注册自定义绑定 向 ko.bindingHandles添加一个子属性来注册一个绑定. ko.bindingHandl ...
- eclipse查看源码失败总结
之前看的网上查看源码的方法,查看了JDK,只是知其然不知所以然. 后来发现要是查看其他源码,总是查看失败. 最开始每次点击Attach Source包到所要查看源码的jar包,但是还是这样. 但是依 ...
- 1、配置JAVA的环境变量
想要成功配置Java的环境变量,那肯定就要安装JDK,才能开始配置的. 想要成功配置Java的环境变量,那肯定就要安装JDK,才能开始配置的. 安装JDK 向导进行相关参数设置.如图: 正在安装程 ...
- iOS-高仿支付宝手势解锁(九宫格)
概述 高仿支付宝手势解锁, 通过手势枚举去实现手势密码相对应操作. 详细 代码下载:http://www.demodashi.com/demo/10706.html 基上篇[TouchID 指纹解锁] ...
- hdu1690Bus System--解题报告
题意:有一个公交系统的收费标准例如以下表: 然后问:给出 这些L1~4 & C1~4的值,然后 N个站.列出每一个站的X坐标.然后询问M次,问两个站台的最小花费 题解:那么这里非常明显是最短路 ...
- @NotEmpty、@NotNull 和 @NotBlank 的区别
1. 三者主要区别如下: @NotEmpty :用于集合类,不能为null,且size>0 @NotNull:不能为null,但可以为empty,没有size的约束 @NotBlank:只用于S ...
- 使用Python操作Memcached
1.安装 yum install memcached easy_install python-memcached 2.操作memcached import memcache mc = memcache ...
- Ubuntu12.04设置屏幕分辨率
Ubuntu屏幕分辨率设置 Table of Contents 1 概述 2 设置前 3 设置 4 参考 1 概述 我的Ubuntu12.04不知道被我怎么折腾了一番,屏幕的分辨率错乱了,没有办法找到 ...