bash 测试目录是否存在于 makefile 中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20763629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Test whether a directory exists inside a makefile
提问by Dror
In his answer@Grundlefleck explains how to check whether a directory exists or not. I tried some to use this inside a makefile
as follow:
@Grundlefleck在他的回答中解释了如何检查目录是否存在。我尝试了一些在 a 中使用它makefile
,如下所示:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then
echo "Dir exists"
fi
Running make foo.bak
(given that foo.bar
exists) yields the following error:
运行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
The workaround I made was to have a standalone bash script where the test is implemented and I called the script from the makefile
. This, however, sounds very cumbersome. Is there a nicer way to check whether a directory exists from within a makefile
?
我所做的解决方法是使用一个独立的 bash 脚本来实现测试,然后我从makefile
. 然而,这听起来非常麻烦。有没有更好的方法来检查目录中是否存在makefile
?
回答by lurker
Make commands, if a shell command, must be in one line, or be on multiple lines using a backslash for line extension. So, this approach will work:
如果是 shell 命令,make 命令必须在一行中,或者在多行中使用反斜杠进行行扩展。因此,这种方法将起作用:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then echo "Dir exists"; fi
Or
或者
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then \
echo "Dir exists"; \
fi
回答by cforbish
This approach functions with minimal echos:
这种方法以最小的回声起作用:
.PHONY: all
all:
ifneq ($(wildcard ~/Dropbox/.*),)
@echo "Found ~/Dropbox."
else
@echo "Did not find ~/Dropbox."
endif
回答by Anne van Rossum
Act upon the absence of a directory
在没有目录时采取行动
If you only need to know if a directory does not exist and want to act upon that by for example creating it, you can use ordinary Makefile targets:
如果您只需要知道某个目录是否不存在并希望通过例如创建它来对其进行操作,则可以使用普通的 Makefile 目标:
directory = ~/Dropbox
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) does not exist"
mkdir -p $@
.PHONY: all
Remarks:
评论:
- The
|
indicates that make shouldn't care about the timestamp (it's an order-only-prerequisite). - Rather than write
mkdir -p $@
, you can writefalse
to exit, or solve your case differently.
- 该
|
指示,使不应该关心的时间戳(这是一个订单只-的先决条件)。 mkdir -p $@
您可以写入false
退出或以不同的方式解决您的案例,而不是 write 。
If you also need to run a particular series of instructions upon the existenceof a directory, you cannot use the above. In other words, it is equivalent to:
如果您还需要在目录存在时运行特定系列的指令,则不能使用上述指令。换句话说,它等价于:
if [ ! -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does not exist"
fi
There is no else
statement.
没有else
声明。
Act upon the presence of a directory
根据目录的存在采取行动
If you want the opposite if-statement this is also possible:
如果您想要相反的 if 语句,这也是可能的:
directory = $(wildcard ~/Dropbox)
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) exists"
.PHONY: all $(directory)
This is equivalent to:
这相当于:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
fi
Again, there is no else
statement.
再次,没有else
声明。
Act upon both the presence and the absence of a directory
对目录的存在和不存在都采取行动
This becomes a bit more cumbersome, but in the end gives you nice targets for both cases:
这变得有点麻烦,但最终为您提供了两种情况下的不错目标:
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
This is equivalent to:
这相当于:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
else
echo "The ~/Dropbox folder does not exist"
fi
Naturally, the wildcard expansion might be slower than an if-else-statement. However, the third case is probably quite rare and is just added for completeness.
自然地,通配符扩展可能比 if-else 语句慢。但是,第三种情况可能非常罕见,只是为了完整性而添加。
回答by Anne van Rossum
Try this:
尝试这个:
.PHONY: all
something:
echo "hi"
all:
test -d "Documents" && something
This will execute the commands under something
only if Documents
exists.
这将something
仅在Documents
存在时执行下面的命令。
In order to address the problemnoted in the comments, you can make a variable like this:
为了解决评论中提到的问题,您可以创建一个这样的变量:
PATH_TEST = ~/SomeDirectory
test -d $(PATH_TEST) && something
回答by fuenfundachtzig
I had a case where I wanted to define a variable based on the test whether a directory exists or not at the top-most levelof the Makefile
where the approaches described above don't work. I found herea nice solution which can be used like this:
我有,我想在一个目录是否存在与否来定义基于测试变量的情况下,最顶层的Makefile
,其中的途径上述不起作用。我在这里找到了一个很好的解决方案,可以这样使用:
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
This will modify the variable INCLUDES
based on whether the directory stored in MY_DIRNAME
exists or not.
这将INCLUDES
根据存储的目录是否MY_DIRNAME
存在来修改变量。
(Motivation: In my case this variable would be used in another Makefile
included later by the first:
(动机:在我的情况下,这个变量将在第一个Makefile
稍后包含的另一个变量中使用:
include $(SFRAME_DIR)/Makefile.common
I wanted to have the same Makefile
work in two different environments in a simple way.)
我想以Makefile
一种简单的方式在两个不同的环境中进行相同的工作。)
回答by Anne van Rossum
There is a very different answer that allows you to use your if
statements as you envisioned them in one shell:
有一个非常不同的答案,它允许您if
在一个 shell 中使用您设想的语句:
.ONESHELL:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then
echo "Dir exists"
fi
Note that the only difference is the ONESHELL special target.
请注意,唯一的区别是 ONESHELL特殊目标。
回答by user3020921
I use the following to detect if a file or a directory exists and act upon it :
我使用以下内容来检测文件或目录是否存在并对其采取行动:
$(if $(filter expected,$(wildcard *)), the expected file exists)
With your request :
根据您的要求:
.PHONY: ~/Dropbox
~/Dropbox:
echo "Dir exists"
foo.bak: foo.bar | $(if $(filter ~/Dropbox,$(wildcard ~/*)), the expected file exists)
Which can further be simplify :
这可以进一步简化:
foo.bak: foo.bar | $(wildcard ~/Dropbox)