Dav*_*yan 319 makefile gnu-make
例如,我的makefile中有类似的东西:
all:
cd some_directory
Run Code Online (Sandbox Code Playgroud)
但是当我输入时,我make只看到'cd some_directory',就像在echo命令中一样.
fal*_*tro 564
它实际上是在执行命令,将目录更改为some_directory,但是,这是在子进程shell中执行的,并且既不影响make也不影响你正在使用的shell.
如果您要在其中执行更多任务some_directory,则需要添加分号并附加其他命令.请注意,您不能使用换行符,因为make将它们解释为规则的结尾,因此为清晰起见而使用的任何换行符都需要通过反斜杠进行转义.
例如:
all:
cd some_dir; echo "I'm in some_dir"; \
gcc -Wall -o myTest myTest.c
Run Code Online (Sandbox Code Playgroud)
另请注意,即使添加反斜杠和换行符,每个命令之间也必须使用分号.这是因为shell将整个字符串解析为单行.如注释中所述,您应该使用'&&'来连接命令,这意味着只有在前面的命令成功时它们才会被执行.
all:
cd some_dir && echo "I'm in some_dir" && \
gcc -Wall -o myTest myTest.c
Run Code Online (Sandbox Code Playgroud)
这在进行破坏性工作时尤其重要,例如清理工作,否则cd如果因任何原因失败,你将摧毁错误的东西.
一个常见的用法是在子目录中调用make,您可能需要查看它.这有一个命令行选项,所以你不必cd自己打电话,所以你的规则看起来像这样
all:
$(MAKE) -C some_dir all
Run Code Online (Sandbox Code Playgroud)
它将改变some_dir并执行Makefile目标"all".作为最佳实践,请使用$(MAKE)而不是make直接调用,因为它会注意调用正确的make实例(例如,如果您为构建环境使用特殊的make版本),并且在运行时提供稍微不同的行为使用某些开关,例如-t.
对于记录,总是使echos执行它执行的命令(除非明确禁止),即使它没有输出,这就是你所看到的.
Chn*_*sos 80
从开始GNU make 3.82,您可以使用.ONESHELL特殊目标在shell的单个实例中运行所有配方行(粗体强调我的):
- 新的特殊目标:
.ONESHELL指示make调用shell的单个实例并为其提供整个配方,无论它包含多少行.[...]
.ONESHELL:
all:
cd ~/some_dir
pwd # Prints ~/some_dir if cd succeeded
Run Code Online (Sandbox Code Playgroud)
Joe*_*oeS 21
这是一个处理目录和制作的可爱技巧.而不是使用多行字符串,或"cd;" 在每个命令上,定义一个简单的chdir函数,如下所示:
CHDIR_SHELL := $(SHELL)
define chdir
$(eval _D=$(firstword $(1) $(@D)))
$(info $(MAKE): cd $(_D)) $(eval SHELL = cd $(_D); $(CHDIR_SHELL))
endef
Run Code Online (Sandbox Code Playgroud)
然后你所要做的就是在你的规则中调用它:
all:
$(call chdir,some_dir)
echo "I'm now always in some_dir"
gcc -Wall -o myTest myTest.c
Run Code Online (Sandbox Code Playgroud)
您甚至可以执行以下操作:
some_dir/myTest:
$(call chdir)
echo "I'm now always in some_dir"
gcc -Wall -o myTest myTest.c
Run Code Online (Sandbox Code Playgroud)
它到达那里后你想要它做什么?每个命令都在子shell中执行,因此subshell更改目录,但最终结果是下一个命令仍在当前目录中.
使用GNU make,您可以执行以下操作:
BIN=/bin
foo:
$(shell cd $(BIN); ls)
Run Code Online (Sandbox Code Playgroud)
这是我使用的模式:
.PHONY: test_py_utils
PY_UTILS_DIR = py_utils
test_py_utils:
cd $(PY_UTILS_DIR) && black .
cd $(PY_UTILS_DIR) && isort .
cd $(PY_UTILS_DIR) && mypy .
cd $(PY_UTILS_DIR) && pytest -sl .
cd $(PY_UTILS_DIR) && flake8 .
Run Code Online (Sandbox Code Playgroud)
我采用这种模式的动机是:
$(MAKE) -C some_dir all&&),因为它的可读性较差,而且我担心在编辑制作配方时会犯错。.ONESHELL特殊目标,因为:
.ONESHELL会导致执行配方的所有行,即使较早的行之一因非零退出状态而失败也是如此。诸如调用之类的解决方法set -e是可能的,但是必须为 makefile 中的每个配方实现此类解决方法。| 归档时间: |
|
| 查看次数: |
183536 次 |
| 最近记录: |