English 中文(简体)
有没有分享有趣的Makefile用法?
原标题:
  • 时间:2008-12-27 18:15:45
  •  标签:

“make” 不仅在构建编程项目时有用,而且在其他领域似乎被低估了。

例如,许多 shell 脚本可以重写为 Makefile,以允许独立的部分并行运行(使用“make -jXX”),从而使所有 CPU 核保持繁忙,并带有显式声明的依赖项作为附加优势,以防您考虑重新排序一些具有副作用的任务在您的 shell 脚本中。

你有没有任何有趣的故事来分享使用make/ Makefile的非传统方式?你是否使用其他实用程序作为廉价作业调度器?

最佳回答

创建并行性对于 Shell 脚本非常方便。比如你想要获取一整个主机集群的运行时间(或者基本上执行任何慢速操作)。你可以用循环来完成:

cat hosts | while read host; do echo "$host: $(ssh $host uptime)"; done

这个功能可以实现,但速度较慢。您可以通过生成子Shell并行处理。

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)。

问题回答

除了编程中明显的用途,我看到过Makefile被用来在服务器上执行重复的任务,以管理系统设置,例如创建用户/组,软件包升级/更新以及将配置文件复制到适当位置。我也看到过(并使用过)在基于Ruby的环境中使用rake来完成这个任务。

我听说的最复杂的例子是ISConf,一种配置管理工具。我从卢克·卡尼斯(Luke Kanies)那里听说的,他是Puppet的作者,在他的博客上介绍了它。

根据制作的种类,您可以使用可执行的makefile与shell脚本来轻松地处理任务的依赖关系...例如,在需要启动10个服务的情况下(即服务二需要在启动之前服务一处于活动状态),可以通过makefile轻松实现。

很多GNU / Linux打包者会利用它,即debian / rules和其他工具。因此,如果正确执行,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上的时间戳。关键是自动变量$?,它保存了所有前提比规则目标新的列表。

这可能意味着我的想象力不够,但很难在一个 Makefile 中实现足够的灵活性以供这样使用。 obvious 的方法是在 make 命令行上指定宏值。

make -f script.mk MACRO="list of files on which to operate"

那比一个简单的shell脚本更冗长 - 而且你失去了使用shell文件名扩展的简单能力。对此的解决方法是:

make -f script.mk MACRO="$(echo *[io]*)"

我认为这个关于为什么不在makefile的顶部使用#!/bin/make的SO问题是一种奇怪的使用(可执行)makefile,但那里的目标不是为了做不寻常的事情(只是无聊的老软件构建);只是使用不寻常的调用机制来运行make

使用这种技术,您可以将调用简化为:

script.mk MACRO="$(echo *[io]*)"

那仍然比较详细:

script *[io]*

我认为可以编写脚本来调用 make。所有这一切都取决于。我并不确信能够从中获得足够的收益。你的情况可能有所不同。

我的工作使用一个奇怪的东西:依赖关系不存在,因此它总是重建所有东西。

最好使用批处理文件。

make are also used to drive process ........ i came to know of this recently , not just individual installation or managing build but the whole process. Previously i thought that make was to be used for compilation of projects only but where ever there is a possibility of a dependency or a chain of activity that needs to be performed , make can be used there ... i recently saw a code that manages everything for a process till delivery/deployment , including data processing-updation ( 24hrs +).... good thing :)





相关问题
热门标签