ifeq和ifneq不一致

时间:2014-04-25 16:18:32

标签: if-statement makefile

我无法弄清楚为什么在下面两个不同的版本产生不同的结果:

$(INCLUDE_DIR)/%: TRGT_PATH = \
    $(INCLUDE_DIR)/$(patsubst $(word 1,$(subst /, ,$(dir $*)))/%,%,$*)
$(INCLUDE_DIR)/%: INCLUDEDS = $(TRGT_PATH)
$(INCLUDED_FILES) : $(INCLUDE_DIR)/%: %
ifeq ($(TRGT_PATH),$(findstring $(TRGT_PATH),$(INCLUDEDS)))
    @echo [INC][WARN] File $(TRGT_PATH) already exists while copying from $*
else
    @echo $(findstring $(TRGT_PATH),$(INCLUDEDS))
    @echo [INC] $* $(TRGT_PATH)
    @cp $* $(TRGT_PATH)
endif

输出:

[INC][WARN] File include/GeometricObject.h already exists while copying from engine/GeometricObject.h
[INC][WARN] File include/util.h already exists while copying from engine/util.h
[INC][WARN] File include/util.h already exists while copying from test/util.h

如果我将行ifeq ($(TRGT_PATH),$(findstring $(TRGT_PATH),$(INCLUDEDS)))更改为ifneq (,$(findstring $(TRGT_PATH),$(INCLUDEDS))),则输出为:

include/GeometricObject.h
[INC] engine/GeometricObject.h include/GeometricObject.h
include/util.h
[INC] engine/util.h include/util.h
include/util.h
[INC] test/util.h include/util.h

据我所知$(findstring t,l)如果t位于t,则返回l,否则返回空字符串。但是输出(如果VAR等于LIST)仍然是:

foo
bar

有人可以解释一下吗?

PS:我测试了一个更简单的代码并且工作正常......

1 个答案:

答案 0 :(得分:1)

如果您提供了完整的示例,包括VARLIST的值,我们就能提供帮助。事实上,我所能说的只是"它适用于我",所以你不能在你的问题中准确地报告你的环境:

$ cat Makefile
VAR = v
LIST = v
all:
ifneq (,$(findstring $(VAR),$(LIST)))
        @echo foo
else
        @echo bar
endif

$ make
foo

ETA:

啊哈。好吧,你的问题与findstring完全无关,所以你原来的问题无法回答也就不足为奇了。

问题在于您尝试在非配方环境中使用特定于目标的变量,而the documentation明确指出它们在配方之外不可用。

ifeq等语句类似于预处理程序语句:它们在正在解析makefile时进行评估,而不是在调用方法时。因此,调用TRGT_PATH / INCLUDEDSifeqifneq的值是这些变量的全局值(可能是空的)字符串,如果他们没有设置,否则不是特定于目标的值。