14

“make”不仅对构建您的编程项目有用,而且在其他领域似乎没有得到充分利用。

例如,可以将许多 shell 脚本重写为 Makefile 以允许独立部分并行运行(使用“make -jXX”)以保持所有 CPU 内核繁忙,并显式声明依赖项作为额外的好处,以防万一考虑在你的 shell 脚本中重新排序一些有副作用的任务。

你有什么不寻常的使用 make / Makefiles 的有趣故事要分享吗?您是否使用其他一些实用程序作为廉价的作业调度程序?

4

7 回答 7

21

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

于 2008-12-30T09:34:19.313 回答
3

除了在编程中的明显用途之外,我还看到 Makefile 用于在服务器上执行重复性任务以管理系统设置,例如用户/组创建、包升级/更新以及将配置文件复制到位。我还看到(并使用过)rake 在基于 Ruby 的环境中执行此操作。

我听说过的最复杂的例子是ISConf,一个配置管理工具。我是从Puppet的作者 Luke Kanies在他的博客上听说的。

于 2008-12-30T08:42:55.907 回答
2

根据“make”的种类,您可以通过使用可执行的 makefile 与 shell 脚本来处理任务的依赖关系..即在一个 init 脚本需要启动 10 个服务的场景中......一个接一个(即服务两个需要服务一个在启动之前启动并活着),它很容易通过生成文件完成。

很多 GNU/Linux 打包器都使用这个,例如 debian/rules 和其他。所以,是的,如果操作正确,make 在启动程序和构建程序方面同样出色。

问题是,并不是每个人都安装了构建工具链……所以 shell 脚本或批处理文件仍然是可移植的(因此是“正确的”)方法。

于 2008-12-30T08:51:31.457 回答
1

这可能意味着我的想象力不足,但是很难在 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。

于 2008-12-27T22:52:08.267 回答
1

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. 关键是自动变量$?,它包含比规则目标更新的所有先决条件的列表。

于 2018-02-15T13:41:49.263 回答
0

我的工作使用了一个奇怪的东西:依赖项不存在,所以它总是重建一切。

还不如使用批处理文件。

于 2008-12-27T18:19:35.383 回答
0

make 也用于驱动进程........我最近才知道这一点,不仅仅是个人安装或管理构建,而是整个过程。以前我认为 make 仅用于编译项目,但只要有可能需要执行的依赖项或活动链,make 就可以在那里使用......我最近看到了一个管理代码直到交付/部署的流程的一切,包括数据处理更新(24小时+)....好东西:)

于 2013-04-18T06:24:41.837 回答