首页 > 解决方案 > Makefile foreach 编译主题

问题描述

我目前正在尝试一次性编译所有主题,但我似乎无法让它工作。

例如:

THEMES := theme_a theme_b theme_c theme_d
build_themes: 
     $(foreach THEME, $(THEMES), sass web/themes/$(THEME)/scss/style.scss web/themes/$(THEME)/css/style.css)

但它只是编译第一个主题而不是全部。

我的迭代有问题吗?

编辑 在 Renaud Pacalet 的建议之后:

RUBY    =$(whereis ruby)
SASSC   = $(RUBY) sass --style compressed

THEMES  := theme_a theme_b theme_c theme_d
SASSDIR = build/scss
CSSDIR  = web/themes/custom-themes
SASS    := $(wildcard $(SASSDIR)/style_*.scss)
CSS     := $(patsubst $(SASSDIR)/style_%.scss, $(CSSDIR)/%/css/style.css, $(SASS))

all: $(CSS)

$(CSSDIR)/%/css/style.css: $(SASSDIR)/style_%.scss
    $(SASSC) $< $@

但我似乎仍然无法让它工作

标签: foreachmakefile

解决方案


Make 不是另一种脚本语言。它是一个具有构建功能的依赖管理实用程序。告诉它如何编译任何主题:

web/themes/%/css/style.css: web/themes/%/scss/style.scss
    sass $< $@

请注意,配方行 ( sass $@ $<) 以制表符开头,而不是空格。

这是一个模式规则$<$@是两个自动变量,它们分别由规则的第一个先决条件和它的目标替代。

该规则意味着任何命名的 CCS 都web/themes/<something>/css/style.css依赖于(唯一的)先决条件web/themes/<something>/scss/style.scss。如果 make 被告知构建一个 CSS,它将搜索相应的 SCSS。如果它没有找到 SCSS,它将引发错误。如果找到,它将比较 CSS 和 SCSS 的最后修改日期。如果 CSS 比 SCSS 更新,make 会认为 CSS 是最新的,它不会做任何事情。否则它会认为 CSS 已经过时,它会扩展配方(通过替换$@and $<)并将其传递给 shell。

接下来,告诉 make 您希望编译所有主题:

THEMES := theme_a theme_b theme_c theme_d
CSS    := $(patsubst %,web/themes/%/css/style.css,$(THEMES))

all: $(CSS)

就是这样。只需调用make all即可完成工作。

这里要记住的最重要的事情是,由于这种结构:

target: prerequisite
    recipe

make 会比简单的脚本循环做得更好:只有当 CSS 缺失或比相应的 SCSS 更旧时,它才会重新编译主题。-j8如果使用选项 ( )调用,make -j8 all它甚至会通过并行启动多达 8 个作业来并行化工作。

奖励:make 还可以找到所有 SCSS 并计算所有可构建 CSS 的列表:

DIR  := web/themes
SCSS := $(wildcard $(DIR)/*/scss/style.scss)
CSS  := $(patsubst $(DIR)/%/scss/style.scss,$(DIR)/%/css/style.css,$(SCSS))

all: $(CSS)

$(DIR)/%/css/style.css: $(DIR)/%/scss/style.scss
    sass $< $@

推荐阅读