第一次来这里。我对makefile很新。这是我当前的makefile:
# Closure compiler php script path
closure = ../../cli/scripts/Compilers/closure.php
# Destination directory
dest = ../../static/js/
# Build directory
build = build/
# Tell "make" to search build and destination dirs
vpath %.o $(build)
vpath %.js $(dest)
all: main.js
@echo "Done.";
main.js: \
date.o \
jquery.autocomplete.o \
jquery.bullseye.o \
jquery.clickopen.o \
jquery.fbmodal.o \
jquery.helpers.o \
jquery.pulljson.o \
jquery.thumbrotate.o \
jquery.timefmt.o \
jquery.tools.o \
layout.main.o
cat $^ > $(dest)$@
%.o: %.js
php $(closure) $*.js $(build)$@
clean:
rm -rf $(build)*.o
rm -rf $(dest)*.js
问题在于以下行:
cat $^ > $(dest)$@
。
应该将所有必备对象(缩小的javascript)捕获到一个最终的js库中。根据makefile文档,$^
是一个自动变量,它包含一系列先决条件及其所在的目录。根据我的经验,它的行为有所不同,具体取决于是否需要编译的先决条件。
如果先决条件是最新的,则此代码可以正常运行,$^
包含如下列表:
build/date.o build/jquery.autocomplete.o build/jquery.bullseye.o....
但是,如果先决条件需要全新编译,那么$^
会删除目录部分,如下所示:
date.o jquery.autocomplete.o jquery.bullseye.o
只有需要重新编译的文件才会删除目录部分。
我设法通过替换
来解决这个问题 cat $^ > $(dest)$@
带
cat $(addprefix $(build), $(^F) ) > $(dest)$@
。
我不喜欢它,因为:
$(^F)
已被半弃用感谢
答案 0 :(得分:1)
看这里:
# Tell "make" to search build and destination dirs
vpath %.o $(build)
如果Make正在寻找foo.o
,它将首先查看本地目录。如果在那里找不到foo.o
,它会在$(build)
中查找(即build/
,您可能会重新考虑您的变量名称。)
如果Make foo.o
无法在任何地方找到它,那该怎么办?有了这条规则:
%.o: %.js
php $(closure) $*.js $(build)$@
此规则违反了makefile的重要指南,因为目标(foo.o
)不是实际构建的内容的名称(build/foo.o
)。
现在考虑Make尝试执行此规则时会发生什么:
main.js: date.o ...
cat $^ > $(dest)$@
因此,如果date.o
是最新的,那么它就在build/
中。 Make在那里找到它,自动变量$^
扩展为build/date.o ...
但是如果必须重建date.o
,那么Make会查看%.o
规则,该规则承诺构建date.o
(不 build/date.o
) ,因此Make将该规则用于其中,$^
扩展为date.o ...
有几种方法可以解决这个问题。我做这样的事情:
OBJS := date.o jquery.autocomplete.o jquery.bullseye.o ...
OBJS := $(addprefix $(build),$(OBJS))
$(dest)main.js: $(OBJS)
cat $^ > $@
# you might have to tinker with this rule a little
$(build)%.o: %.js
php $(closure) $< $@