在大多数Android.mk文件中,我找到一行运行如下:
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
我理解这一行采用:=
右侧的表达式,并将其分配给符号LOCAL_SRC_FILES
。我了解$(LOCAL_PATH)
取LOCAL_PATH
符号的值。但我还有两个问题:
%=%
部分是什么?$(LOCAL_PATH)
嵌套在更广泛的$(FILE_LIST:...)
表达式中的重要性是什么?这是普通的makefile语法(我不熟悉makefile)或其他什么吗?我在哪里可以找到这种语法的指南? (不要告诉我Android.mk指南:它没有处理%符号。)
示例值可能有助于我们讨论这个问题。我们假设$(LOCAL_PATH)
是/Users/Jeff/dev/
。让我们说$(FILE_LIST)
没有进一步的复杂化是/Users/Jeff/dev/aaa.c /Users/Jeff/dev/bbb.c /Users/Jeff/dev/ccc.c
。上述作业如何为LOCAL_SRC_FILES
?
答案 0 :(得分:1)
这是GNU make语法,用于替换字符串变量的值。在这种情况下,请获取字符串列表,对于以/Users/Jeff/dev/
开头的每个字符串,请关闭此前缀。
这个技巧经常在Android.mk中使用,因为NDK期望LOCAL_SRC_FILES中的文件名称相对到LOCAL_PATH。
答案 1 :(得分:1)
Android makefile旨在使用GNU make运行。该文档可用online,也可随附您的发行版。
您要问的语法是substitution references;基本上,%
是匹配零个或多个字符的通配符,左侧的匹配项被替换为右侧。
因此$(FILE_LIST:$(LOCAL_PATH)/%=%)
会从$(LOCAL_PATH)/
变量值的开头删除字符串FILE_LIST
(如果它在那里;如果不是,则不会进行任何更改)。
答案 2 :(得分:0)
如果您查看make
文档的Pattern Rules部分,则文档会向您介绍%
字符。例如,这是一条规则:
%.o : %.c
recipe
该规则告诉make
如何创建任何.o
文件:make应查找.c
文件并将配方应用于该文件。在配方中,您可以使用$<
作为完整的.c
文件名,使用$@
作为完整的.o
文件名。例如,这是一个食谱:
gcc -c $< -o $@
-c
编译
-o
输出文件名
文档再次在%
文档的Substitution References部分中显示make
字符:
foo = a.o b.o c.o
bar := $(foo:%.o=%.c)
:=
现在扩展到文件列表
模式中的第一个%
与没有扩展名的文件名匹配,模式中的第二个%
插入前一个匹配项%,因此条形图被分配了列表a.c b.c c.c
。本节还提到:
另一种类型的替换参考允许您使用的全部功能 patsubst功能。它具有相同的格式
$(var:a=b)
,但现在a
必须包含一个%字符。
在make
文档的Functions for String Substitution and Analysis部分,它说:
$(patsubst pattern,replacement,text)
在文本中查找与模式匹配的以空格分隔的单词,并将其替换为替换。 这里的模式可能包含'%',它充当通配符,匹配任何通配符 单词中任何字符的数量。如果替换还包含一个 '%','%'被替换为匹配模式中'%'的文本。
......
替换参考(参见替代参考文献)更简单 获得patsubst函数效果的方法:
$(var:pattern=replacement)
您的substitution reference
:
$(FILE_LIST:$(LOCAL_PATH)/%=%)
使用以下值:
var => FILE_LIST
pattern => /Users/Jeff/dev/% # $(LOCAL_PATH) is /Users/Jeff/dev/
replacement => %
如果FILE_LIST中的某个文件名如下所示:
/Users/Jeff/dev/path/to/program.c
然后模式匹配就像这样排列:
file name: /Users/Jeff/dev/path/to/program.c
pattern: /Users/Jeff/dev/%
和%
匹配path/to/program.c
。由于替换只是%
,因此文件名/Users/Jeff/dev/path/to/program.c
将转换为path/to/program.c
因此,FILE_LIST中的所有文件都将删除前缀/Users/Jeff/dev/
。