根本不要ifeq
在食谱中使用。只需使用普通的 shell 功能。它工作得更好。
.SECONDEXPANSION:
%.pot: $$(dir $$@)*.c
@echo "it works"
if [ ! -f $@ ]; then \
: pot-file does not exist, do something; \
else \
: pot-file already exists, do something else; \
fi
也就是说,在先决条件列表中使用通配符通常不是一个好主意,因为通配符的时间不可靠并且可能导致奇怪的行为。有关问题的一个示例,请参阅使用通配符的陷阱。
如果您需要根据某些外部因素(如操作系统)编写不同的配方内容,那么您需要在 make 解析时检测到该内容,并拥有两个正确切换的配方/makefile 副本。您可以内联执行该操作,但不能内联执行每个食谱。
您最初的尝试(ifeq
在食谱中使用)不起作用。他们不会做你认为他们会做的事。它们可能看起来有效,但并没有按照您期望的方式工作。
考虑这个makefile:
全部:c
a:
@touch a
c: a
.SECONDEXPANSION:
c d:
ifeq (,$(wildcard a))
@echo "a doesn't exist (make)"
else
@echo 'a does exist (make)'
endif
@if [ ! -f a ]; then \
echo "a doesn't exist (sh)"; \
else \
echo 'a does exist (sh)'; \
fi
ifeq (,$$(wildcard a))
@echo "a doesn't exist (make se)"
else
@echo 'a does exist (make se)'
endif
在一个空目录中,您希望make
输出(假设ifeq
按您希望的方式工作):
a does exist (make)
a does exist (sh)
a does exist (make se)
正确的?但事实并非如此。你得到:
a doesn't exist (make)
a does exist (sh)
a does exist (make se)
好吧,你认为,这只是没有二次扩展的事情。但二级扩展版本工作正常。但事实并非如此。
如果你make d
在一个空目录中运行(注意d
目标没有a
作为先决条件列出,所以它不会创建它)你会期望以下输出:
a doesn't exist (make)
a doesn' exist (sh)
a doesn' exist (make se)
正确的?但你实际得到的是:
a doesn't exist (make)
a doesn't exist (sh)
a does exist (make se)
所以看起来二级扩展版本也不起作用。
查看 make 数据库可以解释为什么不这样做。
make -qprR | awk '/c: a/,/^$/; /d:/,/^$/'
在一个空目录中运行,你会看到:
c: a
# Implicit rule search has not been done.
# File does not exist.
# File has been updated.
# Needs to be updated (-q is set).
# variable set hash-table stats:
# Load=0/32=0%, Rehash=0, Collisions=0/2=0%
# commands to execute (from `Makefile', line 12):
@echo "a doesn't exist (make)"
@if [ ! -f a ]; then \
echo "a doesn't exist (sh)"; \
else \
echo 'a does exist (sh)'; \
fi
@echo 'a does exist (make se)'
d:
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# commands to execute (from `Makefile', line 12):
@echo "a doesn't exist (make)"
@if [ ! -f a ]; then \
echo "a doesn't exist (sh)"; \
else \
echo 'a does exist (sh)'; \
fi
@echo 'a does exist (make se)'
如您所见,其中不包含行,而仅包含逻辑ifeq
的“正确”分支。ifeq
这就是问题所在,ifeq
条件是在 make parse 时评估的,这远在任何配方运行之前(因此在任何文件可以创建之前,等等)。