我在 src
目录中有一个网站,该目录有几层深度,包含 html、markdown、less、coffee、png、jpg 和其他资源。我想使用 make 将我的网站构建到 dist
目录中。对于构建,我的意思是
- 将 Markdown 文件转换为 html
- 将coffee编译为js
- 将 less 编译为 css
- 缩小 html 文件
- 缩小js文件(不是从coffee编译的)
- 缩小 css 文件(不是从 less 或 sass 编译的)
- 准备图像(logo.png 变为 [email protected] [email protected] [email protected] )
我有以下文件。 cp
语句将替换为相应的工具来进行转换。
sources = $(shell find src -type f)
t1 := $(sources:.md=.html)
t2 := $(t1:.less=.css)
targets := $(t2:.coffee=.js)
targetdirs = $(dir $(targets))
all: $(targets)
%.html: %.md
cp $< $@
%.css: %.less
cp $< $@
%.js: %.coffee
cp $< $@
这会并排创建输出。因此,src/index.md
变为src/index.html
,src/assets/stylesheets/app.less
变为src/assets/stylesheets/app.css
和 src/assets/scripts/app.coffee
变为 src/assets/scripts/app.js
。我想要做的是更改 make 文件,以便将输出存储在 dist
目录中,因此 src/index.md
转换为 dist/index.html
、src/assets/stylesheets/app.less
编译为 dist/assets/stylesheets/app.css
和 src/asset/scripts/app.coffee
变为 dist/assets/scripts/app.js
。
所以我更改了 makefile,如下所示:
sources = $(shell find src -type f)
t0 := $(subst src/,dist/,$(sources:.md=.html))
t1 := $(t0:.md=.html)
t2 := $(t1:.less=.css)
targets := $(t2:.coffee=.js)
targetdirs = $(dir $(targets))
all: $(targets)
%.html: %.md
mkdir -p $(targetdirs)
cp $< $@
%.css: %.less
mkdir -p $(targetdirs)
cp $< $@
%.js: %.coffee
mkdir -p $(targetdirs)
cp $< $@
现在 make 失败并显示以下内容:
make: *** No rule to make target `dist/assets/scripts/app.js', needed by `all'. Stop.
我能找到的大多数示例都仅限于单个目录,或者将多个源文件编译到单个目标中。
如果不知道源目录的内容,如何实现这一目标?
环境:
- GNU Make 3.81
- OS X 10.11.1
最佳答案
在 make 模式规则中,目标和先决条件中的模式所表示的词干必须完全匹配。遵循这个规则:
%.html: %.md
mkdir -p $(targetdirs)
cp $< $@
如果目标make要构建的是dist/index.html
,那么词干就是dist/index
。因此,它将寻找先决条件 dist/index.md
。这是不存在的。因此,make 会忽略该模式规则,因为它不匹配,并继续寻找可能匹配的更多隐式规则...但没有找到任何规则,因此失败。
您必须修复规则,以便目录中的更改反射(reflect)在模式中:
dist/%.html: src/%.md
mkdir -p $(@D)
cp $< $@
(我不确定为什么你要在每个菜谱中创建所有目录,而不仅仅是当前目录)。现在的词干为dist/index.html
只是 index
,并且先决条件匹配 src/index.md
它会起作用的。
关于makefile - 如何使用make将静态网站构建到dist目录中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34115305/