如何删除重复的Makefile中? [英] How to remove duplication in Makefile?

查看:196
本文介绍了如何删除重复的Makefile中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法来简化这种重复在一个Makefile?

Is there a way to simplify this sort of repetition in a Makefile?

duo = ./node_modules/.bin/duo

build: lib/background/build lib/page/build lib/popup/build

lib/background/build: lib/background/build/build.js lib/background/build/build.css
lib/page/build: lib/page/build/build.js lib/page/build/build.css
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css

lib/background/build/build.js: lib/background/index.js node_modules component.json
  @mkdir -p lib/background/build
  @$(duo) lib/background/index.js > lib/background/build/build.js

lib/page/build/build.js: lib/page/index.js node_modules component.json
  @mkdir -p lib/page/build
  @$(duo) lib/page/index.js > lib/page/build/build.js

lib/popup/build/build.js: lib/popup/index.js node_modules component.json
  @mkdir -p lib/popup/build
  @$(duo) lib/popup/index.js > lib/popup/build/build.js

lib/background/build/build.css: lib/background/index.css node_modules component.json
  @mkdir -p lib/background/build
  @$(duo) lib/background/index.css | $(myth) > lib/background/build/build.css

lib/page/build/build.css: lib/page/index.css node_modules component.json
  @mkdir -p lib/page/build
  @$(duo) lib/page/index.css | $(myth) > lib/page/build/build.css

lib/popup/build/build.css: lib/popup/index.css node_modules component.json
  @mkdir -p lib/popup/build
  @$(duo) lib/popup/index.css | $(myth) > lib/popup/build/build.css

基本上,我想从顶层运行一个简单的使构建命令,并在必要时只重建这些子项目。我想不必使用一个Makefile每个子项目,因为这也是重复的。我试着有关通配符的路径一切都没有制定出来,所以不知道是否有一个连的方式来做到这一点。例如,我试图做这样的事情,但没有运气(无论是js和css类似):

Basically, I want to run a simple make build command from the top level, and it only rebuilds these subprojects if necessary. I would like to not have to use a Makefile for each subproject because that is also repetitive. Everything I've tried in relation to wildcard paths hasn't worked out, so wondering if there is even a way to do this. For example, I tried doing something like this (similar both for js and css) but no luck:

js = $(shell find lib test -type f -name '*.js' ! -path "*build.js")

$(js)/build/build.js: node_modules component.json
  # somehow get the directory such as lib/background based on the make command?
  local dir=$(shell dirname $(shell dirname $@))
  @mkdir -p $(dir)/build
  @$(duo) $(dir)/index.js > $(dir)/build/build.js

任何想法如何使这个干?

Any ideas how to make this DRY?

推荐答案

一个很好的第一次启动会停止重复的对象/等。规则中的机构本身,并使用自动变量,而不是他们。因此,'$ @'目标文件名,'$(@ D)中的目录路径(如目录名)的目标文件名等。

A good first start would be to stop repeating the targets/etc. in the rule bodies themselves and use the automatic variables for them instead. So '$@' for the target filename, '$(@D)' for the directory path (like dirname) of the target filename, etc.

它可以帮助您:

duo = ./node_modules/.bin/duo

build: lib/background/build lib/page/build lib/popup/build

lib/background/build: lib/background/build/build.js lib/background/build/build.css
lib/page/build: lib/page/build/build.js lib/page/build/build.css
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css

lib/background/build/build.js: lib/background/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) lib/background/index.js > '$@'

lib/page/build/build.js: lib/page/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) lib/page/index.js > '$@'

lib/popup/build/build.js: lib/popup/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) lib/popup/index.js > '$@'

lib/background/build/build.css: lib/background/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) lib/background/index.css | $(myth) > '$@'

lib/page/build/build.css: lib/page/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) lib/page/index.css | $(myth) > '$@'

lib/popup/build/build.css: lib/popup/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) lib/popup/index.css | $(myth) > '$@'

然后意识到模式规则是有帮助的当你有目标和共享文件名图案,您可以开始使用那些过于相似的规则体prerequisites。他们也给你一个额外的自动变量

Then realizing that pattern rules are helpful when you have targets and prerequisites that share filename patterns and similar rule bodies you can start using those too. They also give you an extra automatic variable.

您得到这个(中间)阶段:

You get this (intermediate) stage:

duo = ./node_modules/.bin/duo

build: lib/background/build lib/page/build lib/popup/build

lib/background/build: lib/background/build/build.js lib/background/build/build.css
lib/page/build: lib/page/build/build.js lib/page/build/build.css
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css

%/build/build.js: %/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.js > '$@'

%/build/build.js: %/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.js > '$@'

%/build/build.js: %/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.js > '$@'

%/build/build.css: %/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.css | $(myth) > '$@'

%/build/build.css: %/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.css | $(myth) > '$@'

%/build/build.css: %/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.css | $(myth) > '$@'

和他们你看,你真的只得到了两个重复的规则,所以你将它们结合起来。

And them you see that you've really just got two duplicate rules so you combine them.

duo = ./node_modules/.bin/duo

build: lib/background/build lib/page/build lib/popup/build

lib/background/build: lib/background/build/build.js lib/background/build/build.css
lib/page/build: lib/page/build/build.js lib/page/build/build.css
lib/popup/build: lib/popup/build/build.js lib/popup/build/build.css

%/build/build.js: %/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.js > '$@'

%/build/build.css: %/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.css | $(myth) > '$@'

然后,因为make不处理目录的目标/ prerequisites以及人们可能会喜欢,你可以删除的lib /背景/建的lib /页/建的lib /弹出/建中期目标,只是列出实际文件作为prereqs为建立

And then, since make doesn't handle directory targets/prerequisites as well as one might like, you can drop the lib/background/build, lib/page/build, and lib/popup/build intermediate targets and just list the actual files as the prereqs for build.

duo = ./node_modules/.bin/duo

build: lib/background/build/build.js lib/background/build/build.css \
       lib/page/build/build.js lib/page/build/build.css \
       lib/popup/build/build.js lib/popup/build/build.css

%/build/build.js: %/index.js node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.js > '$@'

%/build/build.css: %/index.css node_modules component.json
        @mkdir -p '$(@D)'
        @$(duo) '$*'/index.css | $(myth) > '$@'

我也许应该提到,我没有测试这个(因为缺乏欲望小样目录布局的/ etc。),但转变是直进和概念是相当简单的,因此应该只是罚款。但是,任何事情都是可能的。

I should probably mention that I didn't test this (for lack of desire to mock up the directory layout/etc.) but the transformations were straight-forward and the concepts are fairly simple so it should work just fine. But anything is possible.

要清理建立 prerequisites你可以使用这样的:

To clean up the build prerequisites you could use something like:

build: $(foreach d,background page popup,$(addprefix lib/$d/build/,build.js build.css))

这篇关于如何删除重复的Makefile中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆