例如,我的makefile文件中包含以下内容:
all:
cd some_directory
但是当我键入make
我只看到'cd some_directory',就像在echo
命令中一样。
#1楼
它实际上是在执行命令,将目录更改为some_directory
,但是,这是在子进程shell中执行的,并且既不影响make也不影响您正在使用的shell。
如果要在some_directory
执行更多任务,则需要添加分号并附加其他命令。 请注意,您不能使用换行符,因为它们被make解释为规则的结尾,因此,为清楚起见而使用的任何换行符都必须使用反斜杠进行转义。
例如:
all:
cd some_dir; echo "I'm in some_dir"; \
gcc -Wall -o myTest myTest.c
还请注意,即使您添加了反斜杠和换行符,每个命令之间也必须使用分号。 这是由于shell将整个字符串解析为一行的事实。 如注释中所述,您应使用'&&'联接命令,这意味着它们仅在前面的命令成功执行后才会执行。
all:
cd some_dir && echo "I'm in some_dir" && \
gcc -Wall -o myTest myTest.c
这在进行破坏性工作(例如清理)时尤其重要,因为如果cd
由于任何原因而失败,您将破坏错误的内容。
不过,一种常见用法是在您可能要查看的子目录中调用make。 有一个命令行选项,因此您不必自己调用cd
,因此您的规则将如下所示
all:
$(MAKE) -C some_dir all
它将更改为some_dir
并在其中以目标“ all”执行Makefile
。 最佳做法是使用$(MAKE)
而不是直接调用make
,因为它将注意调用正确的make实例(例如,如果您在构建环境中使用特殊的make版本),并提供使用某些开关(例如-t
运行时,行为略有不同。
为了记录起见,make 总是回显它执行的命令(除非显式取消显示),即使它没有输出,这也是您所看到的。
#2楼
一旦到达目的地,您希望它做什么? 每个命令都在子外壳程序中执行,因此该子外壳程序会更改目录,但最终结果是下一个命令仍在当前目录中。
使用GNU make,您可以执行以下操作:
BIN=/bin
foo:
$(shell cd $(BIN); ls)
#3楼
从GNU make 3.82
,可以使用.ONESHELL
特殊目标在外壳的单个实例中运行所有配方行(加粗强调我的):
- 新的特殊目标:
.ONESHELL
指示make调用该shell的单个实例并向其提供整个配方 ,而不管其包含多少行。 [...]
.ONESHELL:
all:
cd ~/some_dir
pwd # Prints ~/some_dir if cd succeeded
#4楼
像这样:
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
祝好运!
#5楼
更改目录
foo:
$(MAKE) -C mydir
multi:
$(MAKE) -C / -C my-custom-dir ## Equivalent to /my-custom-dir
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3196140