GNU Make:如何在 $(eval) 中调用 $(wildcard)
我正在尝试为我的 Makefile 创建一个通用构建模板,有点像他们在 评估文档。
我似乎无法让通配符函数在评估中工作。我遇到问题的基本代码如下所示。
SRC_DIR = ./src/
PROG_NAME = test
define PROGRAM_template
$(1)_SRC_DIR = $(join $(SRC_DIR), $(1)/)
$(1)_SRC_FILES = $(wildcard $$($(1)_SRC_DIR)*.c)
endef
$(eval $(call PROGRAM_template, $(PROG_NAME)))
all:
@echo $(test_SRC_DIR)
@echo $(test_SRC_FILES)
@echo $(wildcard $(wildcard $(test_SRC_DIR)*.c)
当我用它运行 make 时,输出
./src/test
[correct list of all .c files in ./src/test/]
基本上是,PROGRAM_template 中的通配符调用没有按照我的预期进行评估。调用结果为空列表。
不过,连接调用正在被正确评估。
那么,我做错了什么?我的猜测是这
$$($(1)_SRC_DIR)
是不正确的,但我无法找出正确的方法。
编辑 一旦这个问题解决了,没过多久我就遇到了 eval 的另一个问题。 我将其作为新问题发布在 GNU Make 3.80 eval 错误的解决方法
I'm trying to create a generic build template for my Makefiles, kind of like they discuss in the eval documentation.
I can't seem to get the wildcard function to work within an eval. The basic code I'm having issues with looks like this.
SRC_DIR = ./src/
PROG_NAME = test
define PROGRAM_template
$(1)_SRC_DIR = $(join $(SRC_DIR), $(1)/)
$(1)_SRC_FILES = $(wildcard $($(1)_SRC_DIR)*.c)
endef
$(eval $(call PROGRAM_template, $(PROG_NAME)))
all:
@echo $(test_SRC_DIR)
@echo $(test_SRC_FILES)
@echo $(wildcard $(wildcard $(test_SRC_DIR)*.c)
When I run make with this, the output is
./src/test
[correct list of all .c files in ./src/test/]
Basically, the wildcard call within PROGRAM_template is not being eval'd as I expect it. The call results in an empty list.
The join call is being eval'd correctly though.
So, what am I doing wrong? My guess is that
$($(1)_SRC_DIR)
is not correct, but I can't figure out the right way to do it.
EDIT
Once this was solved, it didn't take long for me to hit another issue with eval.
I posted it as a new question at
Workaround for GNU Make 3.80 eval bug
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用
eval
时,您几乎需要对所有函数和变量进行双重转义。在大多数情况下,唯一不需要需要双重转义的是函数参数(因为call
函数将完全扩展它们)。在这种情况下,从技术上讲,您也不需要双重转义join
或SRC_DIR
,但如果您始终对所有变量和函数进行双重转义,它将简化您的生活使用eval
时。您需要两次转义的原因是使用
eval
时会发生两次扩展。eval
函数本身执行扩展,然后当该块最终被解析为 makefile 语法时(即实际评估时),再次执行扩展。按照您编写的方式,在字符串文字
$( test_SRC_DIR)*.c
上调用wildcard
。如果需要,您可以在您的版本中将wildcard
替换为info
来亲自查看,看看会发生什么。您需要推迟实际调用
通配符
,直到第二次扩展,以便它的参数是扩展的结果$(test_SRC_DIR)
。试试这个:
编辑:发布此内容后,我想我最好对其进行测试以确保它确实有效。在这样做的过程中,我发现了另一个问题。调用函数时应避免在逗号和参数之间添加空格。它会导致在传递给函数的参数前面添加一个文字空格字符,并导致意外的结果。我已经删除了我的版本中函数调用中逗号后面的空格(虽然这对于
join
的调用来说不是问题,但我也删除了那里的空格,因为这是一个好习惯进入)。You need to double escape virtually all of the functions and variables when you use
eval
. In most cases, the only things that don't need to be double-escaped are function arguments (because thecall
function will fully expand them). In this case, you technically don't need to double-escapejoin
orSRC_DIR
either, but it will simplify your life if you just always double-escape all variables and functions when usingeval
.The reason you need the double escapes is that expansion happens twice when using
eval
. Theeval
function itself performs expansion, and then expansion is done again when the block is finally parsed as makefile syntax (i.e. when it is actually evaluated).The way you've got it written,
wildcard
is invoked on the string literal$( test_SRC_DIR)*.c
. If you want, you can see this for yourself by replacingwildcard
withinfo
in your version and see what happens.You need to hold off on actually invoking
wildcard
until the second expansion, so that it's argument is the result of the expansion of$(test_SRC_DIR)
.Try this:
EDIT: After posting this, I thought I'd better test it out to make sure it actually works. In doing so, I discovered another problem. You should avoid putting spaces between the comma and argument when calling functions. It causes a literal space character to be prepended to the argument that is passed to the function and leads to unintended results. I've removed the spaces after the commas in the function calls in my version (while this isn't a problem for the call to
join
, I removed the space there as well just because it's a good habit to get into).