例如,我在makefile中有这样的东西:
all:
cd some_directory
但是当我输入make时,我只看到'cd some_directory',就像在echo命令中一样。
例如,我在makefile中有这样的东西:
all:
cd some_directory
但是当我输入make时,我只看到'cd some_directory',就像在echo命令中一样。
当前回答
从GNU make 3.82(2010年7月)开始,你可以使用.ONESHELL特殊目标在shell的单个实例化中运行所有食谱(粗体强调我的):
新的特殊目标:. oneshell指示make调用shell的单个实例,并为其提供整个配方,而不管它包含多少行。
.ONESHELL: # Applies to every targets in the file!
all:
cd ~/some_dir
pwd # Prints ~/some_dir if cd succeeded
another_rule:
cd ~/some_dir
pwd # Prints ~/some_dir if cd succeeded
注意,这相当于手动运行
$(SHELL) $(.SHELLFLAGS) "cd ~/some_dir; pwd"
# Which gets replaced to this, most of the time:
/bin/sh -c "cd ~/some_dir; pwd"
命令没有&&链接,所以如果你想在第一个失败的命令上停下来,你还应该在你的.SHELLFLAGS中添加-e标志:
.SHELLFLAGS += -e
此外,-o pipefail标志可能也会感兴趣:
如果设置了该值,则管道的返回值为最后一个(最右边)以非零状态退出的命令的值,如果管道中的所有命令都成功退出,则为零。默认情况下,该选项是禁用的。
其他回答
更改dir
foo:
$(MAKE) -C mydir
multi:
$(MAKE) -C / -C my-custom-dir ## Equivalent to /my-custom-dir
从GNU make 3.82(2010年7月)开始,你可以使用.ONESHELL特殊目标在shell的单个实例化中运行所有食谱(粗体强调我的):
新的特殊目标:. oneshell指示make调用shell的单个实例,并为其提供整个配方,而不管它包含多少行。
.ONESHELL: # Applies to every targets in the file!
all:
cd ~/some_dir
pwd # Prints ~/some_dir if cd succeeded
another_rule:
cd ~/some_dir
pwd # Prints ~/some_dir if cd succeeded
注意,这相当于手动运行
$(SHELL) $(.SHELLFLAGS) "cd ~/some_dir; pwd"
# Which gets replaced to this, most of the time:
/bin/sh -c "cd ~/some_dir; pwd"
命令没有&&链接,所以如果你想在第一个失败的命令上停下来,你还应该在你的.SHELLFLAGS中添加-e标志:
.SHELLFLAGS += -e
此外,-o pipefail标志可能也会感兴趣:
如果设置了该值,则管道的返回值为最后一个(最右边)以非零状态退出的命令的值,如果管道中的所有命令都成功退出,则为零。默认情况下,该选项是禁用的。
这里有一个处理目录和制作的可爱技巧。不要在每个命令上使用多行字符串或“cd;”,而是定义一个简单的chdir函数,如下所示:
CHDIR_SHELL := $(SHELL)
define chdir
$(eval _D=$(firstword $(1) $(@D)))
$(info $(MAKE): cd $(_D)) $(eval SHELL = cd $(_D); $(CHDIR_SHELL))
endef
然后你所要做的就是在你的规则中这样调用它:
all:
$(call chdir,some_dir)
echo "I'm now always in some_dir"
gcc -Wall -o myTest myTest.c
你甚至可以这样做:
some_dir/myTest:
$(call chdir)
echo "I'm now always in some_dir"
gcc -Wall -o myTest myTest.c
你希望它到达那里后做什么?每个命令都在子shell中执行,因此子shell会更改目录,但最终结果是下一个命令仍然在当前目录中。
使用GNU make,你可以做如下的事情:
BIN=/bin
foo:
$(shell cd $(BIN); ls)
是这样的:
target:
$(shell cd ....); \
# ... commands execution in this directory
# ... no need to go back (using "cd -" or so)
# ... next target will be automatically in prev dir
好运!