如何在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 

祝你好运!