make中的动态目标

时间:2010-11-25 17:04:44

标签: makefile

我是make的新手,我正在尝试使用它来部署一些javascript文件。我一直在努力解决以下问题,但没有成功。

我的目录结构如下:

helpers/
    foo/
        foo.js
        test/
            test1.js
            test2.js
            ...
    bar/
        bar.js
        test/
            test1.js
            test2.js
            ...
    other helpers...
distrib/
    files ready for distribution
other stuff...

我的makefile应该构建帮助程序等。对于每个帮助器foo,我想在distrib下生成以下文件:foo-version.jsfoo-version-uncommented.jsfoo-version-packed.jsfoo-version-tests.zip。前三个是由foo.js获得的,分别作为副本,通过剥离注释和运行javascript minifier。我已经有了执行这些任务的命令。

版本号应该在文件本身的注释中读取,我可以轻松地使用

def version
    $(shell cat $1 | grep @version | sed -e"s/.*version *//")
endef

我的问题是像foo-version.js这样的目标是动态的,因为它们取决于运行make时读取的版本号。我试图使用模式,但我没有做到这一点。问题是像这样的东西不起作用

helpers := foo bar
helpers: $(helpers)
$(helpers): %: $(call version, %)

因为第二个%在宏调用中没有展开,但是它按字面意思使用。

我需要能够make helpers来构建所有帮助程序或make foo来构建一个帮助程序。第二步是删除版本号较低的distrib下的所有文件。任何想法如何做到这一点?

作为一个附带问题:使用不同的构建工具,这样的任务会更容易吗?我不是专家,可能值得学习别的东西。

2 个答案:

答案 0 :(得分:10)

在GNU make中,您可以使用calleval函数,通常与foreach结合使用:

%-version.js: %.js
   # your recipe here
%-version-uncommented.js: %.js
   # your recipe here
%-version-packed.js: %.js
   # your recipe here
%-version-tests.zip: %.js
   # your recipe here

versions_sfxs := .js -uncommented.js -packed.js -tests.zip
helpers := $(shell ls $(HELPERSDIR))

define JS_template

helpers: $(1)-version$(2)

endef

$(foreach h, $(helpers), \
  $(foreach sfx, $(versions_sfxs), \
    $(eval $(call JS_template,$(h),$(sfx)) \
  ) \
)

此代码未经测试,但它提供了一般的想法。期待花一个下午调试你对空格,制表符,美元符号和反斜杠的使用,就像在shell脚本中一样。 Search Stack Overflow for make eval或其他更多细节和指示。

答案 1 :(得分:-5)

最后我决定编写自己的构建工具PHPmake。它的语法让人想起标准的makefile,但它已经比标准make更强大,并且它很容易扩展,因为makefile本身是用纯PHP编写的。

没有更多调试空间,标签和美元符号! : - )