Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Makefile 使文件成为可能的偶然顺序依赖?_Makefile - Fatal编程技术网

Makefile 使文件成为可能的偶然顺序依赖?

Makefile 使文件成为可能的偶然顺序依赖?,makefile,Makefile,我正在努力调试make的一个问题。make似乎随机地将某些先决条件视为纯订单先决条件,导致它们被排除在依赖于它们的静态库目标之外。大多数情况下,构建工作都会发现,但偶尔会生成一些.cpp文件,但不包括在.a中。当我运行Make with--debug时,我看到可疑先决条件的以下输出 Prerequisite `blah.o' is newer than target `/path/to/foo.a` Prerequisite `blah1.o' is newer than target `/pa

我正在努力调试make的一个问题。make似乎随机地将某些先决条件视为纯订单先决条件,导致它们被排除在依赖于它们的静态库目标之外。大多数情况下,构建工作都会发现,但偶尔会生成一些.cpp文件,但不包括在.a中。当我运行Make with--debug时,我看到可疑先决条件的以下输出

Prerequisite `blah.o' is newer than target `/path/to/foo.a`
Prerequisite `blah1.o' is newer than target `/path/to/foo.a`
Prerequisite `blah2.o' is newer than target `/path/to/foo.a`
No need to remake target `/path/to/foo.a'
对于所有进入.a的prereq,最后一行是我所期望的“必须重新生成target/path/to/foo.a”

因为make在多个子目录中被调用,所以target/path/to/foo.a会被更新几次。我们并没有并行运行make,所以我认为对文件的更新不会相互影响。make似乎故意不更新.a文件,尽管.o文件较新。制作foo.a的配方如下:

$(OBJLIB): $(OBJS)
    $(AR)     $(ARFLAGS) $(OBJLIB) $?
其中ARFLAGS=rv和OBJLIB应为/path/to/foo.a


我认为.o文件被视为仅顺序依赖项,对吗?这里还有什么我遗漏的吗?我使用$(info)输出OBJLIB和OBJS的内容,并且没有错误的管道(“|”)字符进入变量内容,这将导致顺序依赖关系。

您提到了对.a文件的几次更新,因为make在不同的子目录中被调用。可能是信息

No need to remake target `/path/to/foo.a'
来自一个子目录,
较新
-来自另一个子目录。考虑在一个步骤中创建所有对象的LIB。< /P> < P> >尝试此。

$(OBJLIB): $(OBJS)
    $(AR)     $(ARFLAGS) $(OBJLIB) $^
您的问题是变量$?是比目标更新的依赖项列表,$^是所有依赖项的列表

此外,您还可以使用$@for更为惯用

$(OBJLIB): $(OBJS)
    $(AR)     $(ARFLAGS) $@ $^

不幸的是,答案与make无关。据我所知,文件系统才是真正的罪魁祸首。有几个人正在体验构建的成功,但我没有。我们使用公共构建环境的系统之间的区别在于,我构建的是ext3文件系统,而他们使用的是ext4文件系统

由于ext3不支持sub-1s时间戳(ext4支持),因此在某些情况下,当仅使用几个CPP文件调用规则时,它们是在存档被前一次调用更新的同一秒内编译的,并且所有内容都以相同的时间戳结束。将目录复制到ext4文件系统修复了这个问题


真正的解决办法是编写一套适当的制定规则,但至少我们有一个答案,说明为什么它对除我以外的所有人都有效。

我严重怀疑这只是一个虚假的订单设置。还有别的事情。您使用的是什么版本的make?你建在哪个平台上?假设没有上面没有提到的其他事情发生,这似乎是一个bug:说前提条件比目标更新,然后不构建目标,看起来是错误的。您可以尝试下一版本的预发布,看看这是否有帮助:在Fedora15 x86_64上构建,make 3.82。我将尝试make的新版本,看看是否有不同的结果。如果您给我们提供一个最小的完整示例,这将有所帮助。但也存在与make相关的问题。见上面我的答案。你们在用美元吗?变量(错误)。应该使用$^。使用$?只会导致已更改的依赖项最终出现在存档中。您希望所有依赖项都在归档中结束。为此,您需要使用$^。@Ziffusion:这不是真的。archiver有一个很好的特性,它可以增量地从归档中添加或删除对象。不需要完全从头开始删除和重新创建存档,仅仅因为一些对象已更改。你可以把改变过的东西换掉。哦,我多么讨厌你。。。这正是中描述的那种情况。我认识到非递归设置很难实现——特别是对于一个大型的、现有的代码库——但它避免了以错误的顺序运行的问题@Ziffusion-我尝试了你的建议,但仍然不能纠正这个问题。Make甚至懒得更新库,因为时间戳分辨率太低。