我是GNU make的新手,我正在阅读“使用GNU make管理项目 - O'Reilly”一书。
在第2章“构建库”一节中,本书介绍了两种更新存档库的方法(静态 - .a)。
第一个:
libname.a: preq1.o preq2.o
$(AR) $(ARFLGS) $@ $?
第二个:
libname.a(preq1.o): preq1.o
$(AR) $(ARFLGS) $@ $<
libname.a(preq1.o)如何提高更新静态库的性能?
另外我猜如果图书馆有很多成员(数百或数千),第二种格式可能是开销,这是对的吗?
这是以下内置规则吗?
(%): %
# commands to execute (built-in):
$(AR) $(ARFLAGS) $@ $<
提前致谢
答案 0 :(得分:0)
我想我可以根据我对GNU Make实用程序的了解 - 也是有限的 - 来为您提供一个稍微全面的答案。配方的第一种形式仅指定'libname.a'取决于以下目标文件列表。如果这些文件中的任何一个比'libname.a'的最后更新时间更年轻 - 那么'libname.a'将像MadScientist所说的那样从头开始重新创建。从这个意义上说,'libname.a'与任何其他Make目标没有什么不同。在第二种形式中,依赖项本身不是“libname.a”,而是归档中从属对象文件的插入时间戳。在这里,'libname.a'实际上根本没有测试过。在归档中测试每个目标文件的插入时间戳,并且最后修改日期比相应的对象成员文件更年轻的任何DEPENDENT文件然后导致重建目标文件,使用重建的目标文件更新归档文件和然后删除对象文件 - 我个人认为这很棒。有两个警告;第一个是'libname.a'必须已经存在(即使它只是一个空文件),然后make配方才能工作,除非你指定'-c'标志调用make来强制初始创建存档。第二个是线程安全。按成员重建整个存档成员可能会导致并行运行多个配方。在这种情况下,目标存档很可能被破坏(由于与存档上的多个文件句柄相关的长期问题),除非在makefile的顶部指定了'noparallel'指令。为了回答问题的重点,第二种形式更有效,因为只重建和重新插入过时的存档组件模块,而不是从上到下重建的整个存档。希望这会有所帮助 - V.V。