在他的 answer @Grundlefleck 中解释了如何检查目录是否存在。我尝试在
makefile
中使用它,如下所示:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then
echo "Dir exists"
fi
运行
make foo.bak
(假设 foo.bar
存在)会产生以下错误:
echo "foo"
foo
if [ -d "~/Dropbox" ]; then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [foo.bak] Error 2
我所做的解决方法是使用一个独立的 bash 脚本来实现测试,并且我从
makefile
调用该脚本。然而,这听起来非常麻烦。有没有更好的方法来检查目录是否存在于 makefile
中?
Make命令,如果是shell命令,必须在一行中,或者使用反斜杠进行行扩展在多行中。所以,这种方法会起作用:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then echo "Dir exists"; fi
或者
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then \
echo "Dir exists"; \
fi
这种方法的回声最小:
.PHONY: all
all:
ifneq ($(wildcard ~/Dropbox/.*),)
@echo "Found ~/Dropbox."
else
@echo "Did not find ~/Dropbox."
endif
在目录不存在时采取行动
如果您只需要知道某个目录是否不存在并希望通过创建目录等方式对其进行操作,则可以使用普通的 Makefile 目标:
directory = ~/Dropbox
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) does not exist"
mkdir -p $@
.PHONY: all
备注:
|
表示make不应该关心时间戳(这是一个仅订单先决条件)。 mkdir -p $@
退出,或者以不同的方式解决您的情况,而不是写 false
。如果您还需要在目录“存在”时运行一系列特定的指令,则不能使用上述内容。换句话说,它相当于:
if [ ! -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does not exist"
fi
没有
else
声明。
根据目录的存在采取行动
如果您想要相反的 if 语句,这也是可能的:
directory = $(wildcard ~/Dropbox)
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) exists"
.PHONY: all $(directory)
这相当于:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
fi
再次强调,没有任何
else
声明。
根据目录存在和不存在采取行动
这变得有点麻烦,但最终为这两种情况提供了很好的目标:
directory = ~/Dropbox
dir_target = $(directory)-$(wildcard $(directory))
dir_present = $(directory)-$(directory)
dir_absent = $(directory)-
all: | $(dir_target)
@echo "Continuation regardless of existence of ~/Dropbox"
$(dir_present):
@echo "Folder $(directory) exists"
$(dir_absent):
@echo "Folder $(directory) does not exist"
.PHONY: all
这相当于:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
else
echo "The ~/Dropbox folder does not exist"
fi
当然,通配符扩展可能比 if-else-语句慢。然而,第三种情况可能相当罕见,只是为了完整性而添加的。
Makefile
的最顶层,其中上述方法不起作用。我发现
here一个很好的解决方案,可以像这样使用:
MY_DIRNAME=../External
ifneq "$(wildcard $(MY_DIRNAME) )" ""
# if directory MY_DIRNAME exists:
INCLUDES += -I../External
else
# if it doesn't:
INCLUDES += -I$(HOME)/Code/External
endif
这将根据
INCLUDES
中存储的目录是否存在来修改变量
MY_DIRNAME
。(动机:在我的例子中,这个变量将被用在另一个
Makefile
中,稍后由第一个:
include $(SFRAME_DIR)/Makefile.common
我想以简单的方式在两个不同的环境中实现相同的
Makefile
工作。)
$(if $(filter expected,$(wildcard *)), the expected file exists)
根据您的要求:
.PHONY: ~/Dropbox
~/Dropbox:
echo "Dir exists"
foo.bak: foo.bar | $(if $(filter ~/Dropbox,$(wildcard ~/*)), the expected file exists)
可以进一步简化:
foo.bak: foo.bar | $(wildcard ~/Dropbox)
ifeq ($(shell test -d MYDIR && echo 1 || echo 0), 1)
...
endif