如何在makefile中写入“cd”命令?
例如,我在我的makefile中有这样的东西:
all: cd some_directory
但是当我inputmake
我只看到了'cd some_directory',就像在echo
命令中一样。
它实际上正在执行命令,将目录更改为some_directory
,但是,这是在subprocessshell中执行的,并且不影响make和您正在使用的shell。
如果您想在some_directory
执行更多任务,则需要添加一个分号并附加其他命令。 请注意,不能使用换行符作为规则的结尾,因此为清晰起见使用的任何换行符都需要使用反斜线进行转义。
例如:
all: cd some_dir; echo "I'm in some_dir"; \ gcc -Wall -o myTest myTest.c
还要注意,即使添加了反斜杠和换行符,每个命令之间也需要分号。 这是由于整个string被shellparsing为一行。 如注释中所述,您应该使用'&&'来连接命令,这意味着只有在前面的命令成功时才能执行。
all: cd some_dir && echo "I'm in some_dir" && \ gcc -Wall -o myTest myTest.c
在进行破坏性的工作,如清理时,这一点尤其重要,否则,如果cd
出于任何原因失败,您将会破坏错误的东西。
尽pipe如此,通常的做法是在子目录中调用make,您可能需要查看。 这里有一个命令行选项,所以你不必自己调用cd
,所以你的规则看起来像这样
all: $(MAKE) -C some_dir all
这将变成some_dir
并执行目标“all”中的Makefile
。 作为最佳实践,使用$(MAKE)
而不是直接调用make
,因为它会小心地调用正确的make实例(例如,如果您为构build环境使用特殊的make版本),并提供使用某些开关(如-t
运行时稍有不同的行为。
对于logging来说,即使它没有输出,也总是会回应它所执行的命令(除非明确禁止),这就是你所看到的。
从GNU make 3.82
,可以使用.ONESHELL
特殊目标在shell的一个实例中运行所有的配方行:
- 新的特殊目标:
.ONESHELL
指示make调用shell的单个实例,并提供整个配方,而不pipe它包含多less行。 […]
例:
.ONESHELL: all: cd ~/some_dir pwd # this line is correctly run in ~/some_dir if cd succeeded
这是一个可爱的伎俩来处理目录和制作。 而不是使用多行string或“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
祝你好运!