然而,它仅在Windows 7上发生。在Windows XP上,一旦构建完整,不再构建。
我将问题缩小到一个先决条件 - $(jar_target_dir)
。
以下是代码的一部分
# The location where the JAR file will be created.
jar_target_dir := $(build_dir)/chrome
# The main chrome JAR file.
chrome_jar_file := $(jar_target_dir)/$(extension_name).jar
# The root of the JAR sources.
jar_source_root := chrome
# The sources for the JAR file.
jar_sources := bla #... some files, doesn't matter
jar_sources_no_dir := $(subst $(jar_source_root)/,,$(jar_sources))
$(chrome_jar_file): $(jar_sources) $(jar_target_dir)
@echo "Creating chrome JAR file."
@cd $(jar_source_root); $(ZIP) ../$(chrome_jar_file) $(jar_sources_no_dir)
@echo "Creating chrome JAR file. Done!"
$(jar_target_dir): $(build_dir)
echo "Creating jar target dir..."
if [ ! -x $(jar_target_dir) ]; \
then \
mkdir $(jar_target_dir); \
fi
$(build_dir):
@if [ ! -x $(build_dir) ]; \
then \
mkdir $(build_dir); \
fi
因此,如果我只是从$(jar_target_dir)
规则中移除$(chrome_jar_file)
,则可以正常使用。
UPD:
以下是Windows 7上make的基本调试输出
Reading makefiles...
Updating goal targets....
File `all' does not exist.
Prerequisite `../bin/build/chrome' is newer than
target `../bin/build/chrome/alt.jar'.
Must remake target `../bin/build/chrome/alt.jar'.
Creating chrome JAR file.
updating: content/about.js (deflated 66%)
updating: content/sprintf.js (deflated 52%)
...
和统计资料
$ stat ../bin/build/chrome/alt.jar ../bin/build/chrome
File: `../bin/build/chrome/alt.jar'
Size: 29220 Blocks: 32 IO Block: 65536 regular file
Device: 22c6affh/36465407d Inode: 59672695062724268 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ acid) Gid: ( 513/ None)
Access: 2010-05-05 13:03:01.066457300 +0900
Modify: 2010-05-05 13:03:01.088960100 +0900
Change: 2010-05-05 13:03:01.091460400 +0900
File: `../bin/build/chrome'
Size: 0 Blocks: 0 IO Block: 65536 directory
Device: 22c6affh/36465407d Inode: 3940649674014457 Links: 1
Access: (0755/drwxr-xr-x) Uid: ( 1000/ acid) Gid: ( 513/ None)
Access: 2010-05-05 13:03:01.090960400 +0900
Modify: 2010-05-05 13:03:01.090960400 +0900
Change: 2010-05-05 13:03:01.090960400 +0900
你可以看到chrome
dir比alt.jar
SOL: 就像Eric提到的那样,拥有目录先决条件并在其中生成生产文件是个坏主意。每次更新mtime因此“需要重建”。这部分很清楚。 但是,在某些情况下,内部创建的目录和文件的时间戳始终相等。那令人困惑......
答案 0 :(得分:3)
每当您在目录中添加或删除文件时,目录的修改时间都会更改。因此,将目录用作Makefile中的先决条件是很棘手的,特别是如果目录旨在包含在构建期间创建的文件。
如果您使用的是GNU make 3.80或3.81,则可以将目录依赖项声明为order-only
先决条件:
$(chrome_jar_file): $(jar_sources) | $(jar_target_dir)
请注意$(jar_target_dir)
之前的竖线字符(或竖线)。这告诉GNU make只要目录存在就满足依赖性,无论前提条件的修改时间如何。
如果您不使用GNU make,则通常会在目录中使用“虚拟”文件来解决此问题。此文件与目录同时创建,然后您的其他目标依赖于虚拟文件而不是目录本身。这里的优点当然是当其他文件添加到目录时,虚拟文件的修改时间不会改变。这是这样的:
$(chrome_jar_file): $(jar_sources) $(jar_target_dir)/dummy
$(jar_target_dir)/dummy:
echo "Creating jar target dir..."
mkdir -p $(jar_target_dir)
touch $(jar_target_dir)/dummy
答案 1 :(得分:0)
您创建$(jar_target_dir)的规则看起来很可疑。如果它没有可执行位,它会创建目录,这似乎不正确。我的猜测是你想要做像
这样的事情$(jar_target_dir): $(build_dir)
echo "Creating jar target dir..."
[ -e $(jar_target_dir) ] || mkdir $(jar_target_dir)
答案 2 :(得分:0)
我没有Windows 7可以玩(哈!),但看起来好像修改文件时,操作系统会将其所在的目录标记为已修改。
所以你必须重新考虑$(chrome_jar_file)
规则。我建议:
$(chrome_jar_file): $(jar_sources)
@if [ ! -x $(build_dir) ]; then mkdir $(build_dir); fi
@if [ ! -x $(jar_target_dir) ]; then mkdir $(jar_target_dir); fi
...