“make”不仅对构建您的编程项目有用,而且在其他领域似乎没有得到充分利用。
例如,可以将许多 shell 脚本重写为 Makefile 以允许独立部分并行运行(使用“make -jXX”)以保持所有 CPU 内核繁忙,并显式声明依赖项作为额外的好处,以防万一考虑在你的 shell 脚本中重新排序一些有副作用的任务。
你有什么不寻常的使用 make / Makefiles 的有趣故事要分享吗?您是否使用其他一些实用程序作为廉价的作业调度程序?
Make 的并行性对于 shell 脚本特别方便。假设您想获得整套主机的“正常运行时间”(或基本上执行任何缓慢的操作)。您可以循环执行此操作:
cat hosts | while read host; do echo "$host: $(ssh $host uptime)"; done
这有效,但速度很慢。您可以通过生成子外壳来并行化:
cat hosts | while read host; do (echo "$host: $(ssh $host uptime)")&; done
但是现在您无法控制生成多少线程,并且CTRL-C不会完全中断所有线程。
这是 Make 解决方案:将其保存到文件(例如。showuptimes
)并标记为可执行文件:
#!/usr/bin/make -f
hosts:=$(shell cat)
all: ${hosts}
${hosts} %:
@echo "$@: `ssh $@ uptime`"
.PHONY: ${hosts} all
现在运行cat hosts | ./showuptimes
将一一打印正常运行时间。cat hosts | ./showuptimes -j
将并行运行它们。调用者可以直接控制并行化程度 ( -j
),或者可以通过系统负载 ( ) 间接指定它-l
。
根据“make”的种类,您可以通过使用可执行的 makefile 与 shell 脚本来处理任务的依赖关系..即在一个 init 脚本需要启动 10 个服务的场景中......一个接一个(即服务两个需要服务一个在启动之前启动并活着),它很容易通过生成文件完成。
很多 GNU/Linux 打包器都使用这个,例如 debian/rules 和其他。所以,是的,如果操作正确,make 在启动程序和构建程序方面同样出色。
问题是,并不是每个人都安装了构建工具链……所以 shell 脚本或批处理文件仍然是可移植的(因此是“正确的”)方法。
这可能意味着我的想象力不足,但是很难在 makefile 中获得足够的灵活性来进行此类使用。实现它的“明显”方法是在“ make
”命令行上指定宏值。
make -f script.mk MACRO="list of files on which to operate"
这比一个简单的 shell 脚本更冗长 - 而且你失去了使用 shell 文件名扩展的简单能力。解决方法是:
make -f script.mk MACRO="$(echo *[io]*)"
我会提出这个关于Why not use #!/bin/make at the top of makefiles作为(可执行)makefile 的奇怪用法的 SO question,但目标不是做不寻常的事情(只是无聊的旧软件构建);只是为了对make
.
使用该技术,您可以将调用简化为:
script.mk MACRO="$(echo *[io]*)"
这仍然比以下内容更冗长:
script *[io]*
我想script
可以写成调用make
. 这一切都取决于。我不相信有足够的里程可以从中获得。YMMV。
Make 也可以用作同步实用程序。例如:
#!/usr/bin/make -f
FILES = *.html *.js *.css images/*.jpg subpage/*.html
LAST_SYNC = .last_sync
SCP = scp webserver.com:/home/john/public_html
.PHONY: sync
sync : $(LAST_SYNC)
$(LAST_SYNC) : $(FILES)
$(SCP) $?
touch $(LAST_SYNC)
此 Makefile 创建一个空文件.last_sync
,用于记录我们上次将本地存储库与远程存储库同步的时间。每次运行此脚本时,Make 都会检查FILES
自上次运行同步以来列出的任何文件是否已被修改,并将它们复制到服务器,然后更新.last_sync
. 关键是自动变量$?
,它包含比规则目标更新的所有先决条件的列表。
我的工作使用了一个奇怪的东西:依赖项不存在,所以它总是重建一切。
还不如使用批处理文件。
make 也用于驱动进程........我最近才知道这一点,不仅仅是个人安装或管理构建,而是整个过程。以前我认为 make 仅用于编译项目,但只要有可能需要执行的依赖项或活动链,make 就可以在那里使用......我最近看到了一个管理代码直到交付/部署的流程的一切,包括数据处理更新(24小时+)....好东西:)