我有一个像这样开始的Makefile:
CORE_PATH:=$(filter %/makefile_ltlibs.inc,$(MAKEFILE_LIST))
foobar:
@echo "MAKEFILE_LIST = \"$(MAKEFILE_LIST)\""
@echo "filter = \"$(filter %/makefile_ltlibs.inc,$(MAKEFILE_LIST))\""
@echo "CORE_PATH = \"$(CORE_PATH)\""
当我运行gmake foobar
时,得到以下输出:
MAKEFILE_LIST = " GNUmakefile ../../matrixssl.test/crypto/Makefile ../common.mk ../core/makefiles/detect-and-rules.mk ../../matrixssl.test/crypto/makefile.inc makefile ../../matrixssl.test/crypto/makefile_ltlibs.inc"
filter = "../../matrixssl.test/crypto/makefile_ltlibs.inc"
CORE_PATH = ""
[CORE_PATH
在这里怎么可能为空?!
编辑:
我把它做成一个独立的测试用例:
FILTER_LIST1 := " foo bar"
FILTER_LIST2 := " foo bar "
WORD11 := $(filter foo,$(FILTER_LIST1))
WORD12 := $(filter bar,$(FILTER_LIST1))
WORD13 := $(filter foo,"$(FILTER_LIST1) ")
WORD14 := $(filter bar,"$(FILTER_LIST1) ")
WORD21 := $(filter bar,$(FILTER_LIST2))
foobar:
@echo "FILTER_LIST1 = \"$(FILTER_LIST1)\""
@echo "FILTER_LIST2 = \"$(FILTER_LIST2)\""
@echo "WORD11 = \"$(WORD11)\""
@echo "WORD12 = \"$(WORD12)\""
@echo "WORD13 = \"$(WORD13)\""
@echo "WORD14 = \"$(WORD14)\""
@echo "WORD21 = \"$(WORD21)\""
输出
FILTER_LIST1 = " foo bar"
FILTER_LIST2 = " foo bar "
WORD11 = "foo"
WORD12 = ""
WORD13 = "foo"
WORD14 = ""
WORD21 = "bar"
我的结论是,最后一个条目的filter
被打断了。还是我做错了?
make
是与字符串分隔符无关的-像" ' \
等字符不代表要做什么。因此,bar"
实际上是以"
结尾的4个字符的字符串,并且在filter
操作中将与搜索字符串bar
不匹配。
与原始字符串相同:尝试对space分隔的字符串列表%/makefile_ltlibs.inc
中的" GNUmakefile ../../matrixssl.test/crypto/Makefile ../common.mk ../core/makefiles/detect-and-rules.mk ../../matrixssl.test/crypto/makefile.inc makefile ../../matrixssl.test/crypto/makefile_ltlibs.inc"
进行模式匹配不会出现匹配,因为最后的"
破坏了对模式的一致性。
如果您要进行大量的字符串和列表处理,可能会像gmtt这样的GNUmake帮助器库很方便。
MAKEFILE_LIST
的问题来自于这样的事实,即每次make
处理include
指令时,此变量都会扩展。现在,使用:=
设置CORE_PATH
的值将告诉make
立即评估表达式。由于您位于Makefile
的开头,因此MAKEFILE_LIST
仅包含Makefile
(请参见description of the variable中给出的示例),并且过滤器返回空值。
另一方面,一旦完全解析了Makefile
,便会评估配方。因此,在MAKEFILE_LIST
中有更长的序列,可以对其进行过滤。要使用CORE_PATH
获得相同的内容,请使用CORE_PATH = ...
进行定义。然后,仅在使用CORE_PATH
时才扩展定义,而在定义时不扩展(有关变量的这两个“风味”的更多信息,请参见GNU Make manual)。
关于编辑,正如Vroomfondel所提到的,FILTER_LIST1
由3个词组成(您可以通过执行$(words $(FILTER_LIST1))
,"
,foo
和bar"
来看到它们,但都不是bar
。类似地,FILTER_LIST2
有4个单词,"
,foo
,bar
和"
,并且可以在列表中找到bar
。