我无法弄清楚为什么在下面两个不同的版本产生不同的结果:
$(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:我测试了一个更简单的代码并且工作正常......
答案 0 :(得分:1)
如果您提供了完整的示例,包括VAR
和LIST
的值,我们就能提供帮助。事实上,我所能说的只是"它适用于我",所以你不能在你的问题中准确地报告你的环境:
$ 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
/ INCLUDEDS
时ifeq
和ifneq
的值是这些变量的全局值(可能是空的)字符串,如果他们没有设置,否则不是特定于目标的值。