首页 > 解决方案 > 创建目标库时如何跳过不包含的依赖文件之一

问题描述

我想创建一个库,在创建时跳过其中一个不包含的依赖文件。

例如:-

liba.so: a.o b.o c.o test.psm
        <command for creating liba.so, which includes all its dependencies.> 

在这里,当它的任何依赖项发生变化时,我必须创建liba.so文件。但是.so文件应该只包括 .o 文件而不是test.psm文件。

当我们尝试使用非目标文件创建 .so 文件时,它会抛出错误。

请帮助我如何使用 GNUmake 实现这一目标。

标签: makefilegnu-makegnu

解决方案


解决问题的最好方法是避免它。 我认为完全没有理由重建一个已经存在并且自上次构建以来其先决条件没有改变的库。如果出于某种奇怪的原因,想要确保库的时间戳不早于某些相关文档文件的时间戳,那么最好的替代方案就是围绕维护或分发该文件创建一个单独的过程。例如,

  • touch每当文档文件更改时,相应的源文件;或者
  • 相应的源构建文档,例如通过 Doxygen 或类似工具,使其成为与库共享相同先决条件的构建工件;或者
  • 作为安装/分发过程而不是构建过程的一部分来管理时间戳。例如,在安装或分发构建文件之前制作一个不保留时间戳的副本,以便副本中的所有文件在复制时都带有时间戳。

但是如果你必须服从一个不接受回击的尖头老板的指令,那么实际问题的答案是make没有任何特殊的变量或运算符来指定规则的先决条件列表的子集,但你仍然有很多适当编写食谱的选项。这将成为关于规则配方的细节。

如果一个开始

liba.so: a.o b.o c.o
        $(archiver_command) $(archiver_options) a.o b.o c.o

然后可以添加test.psm到先决条件列表中,而无需进行任何其他更改。

然而,假设以这种形式的规则开始:

liba.so: a.o b.o c.o
        $(archiver_command) $(archiver_options) $^

. 该配方使用自动变量$^来引用(整个)先决条件列表,因此如果将其添加test.psm为新的先决条件,那么它也会被包括在内,这是您不想要的。您在这里有多种选择,其中

  • 使用配方中的 shell 代码来处理先决条件列表并删除最后一个元素。这有点恶心。
  • 用以前的形式重写配方,在配方中使用明确的对象列表而不是变量。然而,这带来了额外的维护负担。
  • 通过用户定义的变量指定真正的先决条件,并在配方中使用它。鉴于已经存在这样一个变量是很常见的事实,这可能是特别自然的。

最后一个选择是我的建议。具体来说,它看起来像这样:

A_OBJS = a.o b.o c.o

# ...

liba.so: $(A_OBJS) test.psm
        $(archiver_command) $(archiver_options) $(A_OBJS)

推荐阅读