已经提出过类似的问题,但我不明白他们的答案。
关于匹配,make
的文档说
当目标模式不包含斜杠时(通常情况下) 如果没有),文件名中的目录名将从文件名中删除 在与目标前缀和后缀进行比较之前。 [...] 目录仅为查找隐式目的而被忽略 规则使用,而不是适用该规则。
考虑以下示例:我的makefile是
%.out: input/%.in
echo $<
我执行以下步骤:
mkdir hello
mkdir -p input/hello
touch input/hello/world.in
make hello/world.out
这会导致找不到任何规则如何构建其目标。但实际上,我不明白文档如何解释这种行为,尽管似乎社区同意这是记录在案的行为。另外,我不知道如何规避这一点;不幸的是,诉诸固定目录名称是没有(易于实施)的选择。
答案 0 :(得分:2)
当目标模式不包含斜杠时(通常情况下) 如果没有),文件名中的目录名将从文件名中删除 在与目标前缀和后缀进行比较之前。
Make正在尝试构建文件hello/world.out
,并查找匹配规则。在此规则中,目标模式(%.out
)不包含斜杠,因此在将其与目标world.out
进行比较之前,Make会从文件名中删除目录名称(保留%.out
)。 。它匹配!
将文件名与目标模式进行比较后, 目录名称以及结束它们的斜杠被添加到 从模式规则生成的先决条件文件名 先决条件模式和文件名。
所以词干是world
,并且Make首先根据模式(input/world.in
)构造先决条件名称,然后添加它之前删除的目录名称(hello/
),这样规则需要先决条件hello/input/world.in
,它不存在(并且无法构建)。
一种解决方案是使用the vpath
directive:
vpath %.in input
%.out: %.in
echo $<
现在让我们知道在hello/world.in
中搜索input/
。