Cygwin 始终使处理目标
然而,这种情况仅发生在 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
,因此如果我只是从 $(chrome_jar_file)
规则中删除 $(jar_target_dir)
,它就可以正常工作。
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 更新: 就像埃里克提到的那样,拥有目录先决条件并在其中创建生产文件是个坏主意。每次更新 mtime 时,因此“需要重建”。这部分很清楚。 但是,在某些情况下,其中创建的目录和文件的时间戳始终相同。这很令人困惑...
However it happens only on Windows 7. On Windows XP once it built and intact, no more builds.
I narrowed down the issue to one prerequisite - $(jar_target_dir)
.
Here is part of the code
# 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
so if I just remove $(jar_target_dir)
from $(chrome_jar_file)
rule, it works fine.
UPD:
Here is the basic debug output from make on Windows 7
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%)
...
and stats
$ 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
as you can see chrome
dir is really newer than alt.jar
SOL:
Like Eric mentioned, it was bad idea to have directory prerequisite and make production file inside of it. Each time the mtime is updated hence 'need to rebuild'. This part is clear.
However, for some cases the timestamps of directory and file created inside are always equal. That's confusing...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
每当您在目录中添加或删除文件时,目录的修改时间都会发生变化。因此,在 Makefile 中使用目录作为先决条件是很棘手的,特别是当该目录旨在包含构建期间创建的文件时。
如果您使用的是 GNU make 3.80 或 3.81,则可以将目录依赖项声明为
order-only
先决条件:请注意
$(jar_target_dir)
前面的竖线字符(或竖线) >。这告诉 GNU make 只要目录存在就满足依赖关系,无论先决条件的修改时间如何。如果您不使用 GNU make,通常可以通过使用目录中的“虚拟”文件来解决此问题。该文件与目录同时创建,然后您的其他目标依赖于虚拟文件而不是目录本身。当然,这样做的优点是,当其他文件添加到目录中时,虚拟文件的修改时间不会改变。看起来是这样的:
Whenever you add or remove files in a directory, the modification time of the directory changes. For this reason, it's tricky to use directories as a prerequisite in a Makefile, particularly if the directory is intended to contain files created during the build.
If you are using GNU make 3.80 or 3.81, you can declare the directory dependency as an
order-only
prerequisite:Note the pipe character (or vertical bar) preceding
$(jar_target_dir)
. This tells GNU make that the dependency is satisfied so long as the directory exists, regardless of the modification time of the prerequisite.If you're not using GNU make, this issue is typically addressed with use of a "dummy" file in the directory. This file is created at the same time as the directory, and then your other targets depend on the dummy file instead of the directory itself. The advantage here of course is that the dummy file's modification time doesn't change when other files are added to the directory. Here's what this would look like:
您创建 $(jar_target_dir) 的规则看起来很可疑。如果目录没有可执行位,它会创建该目录,这似乎不正确。我的猜测是你想做类似的事情
Your rule for creating $(jar_target_dir) looks suspicious. It creates the directory if it does not have the executable bit, which does not seem correct. My guess is that you want to do something like
我没有 Windows 7 可以玩(哈!),但看起来好像当您修改文件时,操作系统会将其所在的目录标记为已修改。
因此,您必须重新考虑
$(chrome_jar_file)
规则。我建议:I don't have Windows 7 to play with (hah!), but it looks as if when you modify a file, the OS then marks the directory it's in as being modified.
So you have to rethink the
$(chrome_jar_file)
rule. I suggest: