我正在使用Makefile来帮助我在我的应用程序中执行JS的构建步骤。目标是使用Make的能力仅处理修改过的文件以防止无关的复制等。
构建你需要的JS
所以我一直在努力使Makefile向后工作。 meta.js取决于-min.js,它取决于从$builddir/b/*.js
复制的%origdir/*.js
在查看事物时,似乎我应该能够使用%.js来捕获任何匹配的文件,但是当我尝试这个时,我得到:
make: *** No rule to make target `bookie/static/js/build/b/%-min.js', needed by `bookie/static/js/build/b/meta.js'. Stop.
我正在与之合作,任何人都知道我做错了什么?我希望当我make js
复制已更改的.js文件时,缩小它们,然后重新生成meta.js。
# Makefile to help automate tasks in bookie
WD := $(shell pwd)
PY := bin/python
BOOKIE_JS = bookie/static/js/bookie
JS_BUILD_PATH = bookie/static/js/build
JS_META_SCRIPT = $(PY) scripts/js/generate_meta.py
EXTENSION = $(WD)/extensions
CHROME_BUILD = $(EXTENSION)/chrome_ext/lib
# JAVASCRIPT
#
# Javascript tools for building out combo loader build directory, out meta.js,
# and syncing things over to the chrome extension directory.
.PHONY: js
js: $(JS_BUILD_PATH)/b/meta.js
$(JS_BUILD_PATH)/b/meta.js: $(JS_BUILD_PATH)/b/%-min.js
echo "META"
$(JS_META_SCRIPT) -n YUI_MODULES -s $(JS_BUILD_PATH)/b/ \
-o $(JS_BUILD_PATH)/b/meta.js \
-x -min.js$
$(JS_BUILD_PATH)/b/%-min.js: $(JS_BUILD_PATH)/b/$*.js
echo "MIN"
rm $(JS_BUILD_PATH)/b/meta.js || true
scripts/js/jsmin_all.py $(JS_BUILD_PATH)/b
$(JS_BUILD_PATH)/b/%.js: $(BOOKIE_JS)/$*.js
echo "Initial"
cp $? $(JS_BUILD_PATH)/b/
cp $? $(CHROME_BUILD)/
.PHONY: clean_js
clean_js:
rm -rf $(JS_BUILD_PATH)/* || true
答案 0 :(得分:0)
您的配方有点难以理解,因为您的实用程序不是标准Unix风格的过滤器:它们似乎不将输入文件名作为参数或从stdin读取输入,并且似乎不会将输出写入stdout
我的猜测是(基于文件名中的all
)您的实用程序转换特定目录中的所有文件。这不是make
可以优雅处理的事情:它实际上是为了支持从单个输入文件(依赖项)生成单个输出文件(目标)的规则。
模式规则只允许您同时为整个文件类别指定此类规则,但它们不指定在单个规则中处理文件集合。你似乎试图这样做。
我一直遇到这个make
限制。作为一种变通方法,您可以使用文件所在的目录作为规则的目标和依赖项(如果确保不会在其中创建其他文件),或者使用没有用于标记完成的内容的特殊标记文件一条规则。正确的解决方案需要对make
规则的语法和语义进行基本扩展。
答案 1 :(得分:0)
使通配符不按照您的想法运行。让我们从这条规则开始:
$(JS_BUILD_PATH)/b/%.js: $(BOOKIE_JS)/$*.js
echo "Initial"
cp $? $(JS_BUILD_PATH)/b/
cp $? $(CHROME_BUILD)/
%
意味着它是一个模式规则,因此Make期望在先决条件列表中有相应的%
。相反,它看起来好像你正在尝试使用自动变量$*
(不能在先决条件列表中使用)或通配符*
(如果不使用{ {1}}命令)。试试这种方式:
wildcard
这样可行,但前提是您准确指定了所需的文件;它不会复制dev目录中的每个$(JS_BUILD_PATH)/b/%.js: $(BOOKIE_JS)/%.js
echo "Initial"
cp $? $(JS_BUILD_PATH)/b/
cp $? $(CHROME_BUILD)/
文件(稍后会详细介绍)。
现在为.js
。我无法确切地知道这个规则是如何工作的,但它看起来好像你运行了一个python脚本,它立即对目录中的所有* .js文件起作用。如果这是正确的,那么从-min.js
获得foo-min.js
的规则是没有意义的;应该有一个规则来运行脚本,我们需要一个列出它需要的所有foo.js
文件:
.js
最后,DEV_JS_FILES := $(wildcard $(BOOKIE_JS)/*.js)
BUILD_JS_FILES := $(patsubst $(BOOKIE_JS)/%.js,$(JS_BUILD_PATH)/b/%.js,$(DEV_JS_FILES))
.PHONY: min
min: $(BUILD_JS_FILES)
echo "MIN"
rm $(JS_BUILD_PATH)/b/meta.js || true
scripts/js/jsmin_all.py $(JS_BUILD_PATH)/b
:
meta.js
修改:
我想我明白你在做什么。有几种方法可以做到这一点;最简单的只是将三个规则合并为一个:
$(JS_BUILD_PATH)/b/meta.js: min
echo "META"
$(JS_META_SCRIPT) -n YUI_MODULES -s $(JS_BUILD_PATH)/b/ \
-o $(JS_BUILD_PATH)/b/meta.js \
-x -min.js$
此操作仅适用于开发中DEV_JS_FILES := $(wildcard $(BOOKIE_JS)/*.js)
$(JS_BUILD_PATH)/b/meta.js: $(DEV_JS_FILES)
echo "Initial"
cp $? $(JS_BUILD_PATH)/b/
cp $? $(CHROME_BUILD)/
echo "MIN"
rm $(JS_BUILD_PATH)/b/meta.js || true
scripts/js/jsmin_all.py $(JS_BUILD_PATH)/b
rm $(addprefix $(JS_BUILD_PATH)/b/,$?)
echo "META"
$(JS_META_SCRIPT) -n YUI_MODULES -s $(JS_BUILD_PATH)/b/ \
-o $(JS_BUILD_PATH)/b/meta.js \
-x -min.js
rm $(JS_BUILD_PATH)/b/*-min.js
以上.js
的{{1}}文件(如果meta.js
尚不存在,则仅适用于所有文件。)