如何告诉Makefile哪个目标满足哪些依赖项?



我正在创建一个Makefile来驱动从XML文档存档生成EPUB3电子书。我很难理解如何告诉使一个特定的文件名或目录依赖可以由另一个目标来满足。

非常简单:

dir:
       mkdir testing
files: testing
       echo foobar >testing/blort

这当然产生:

% make files
make: *** No rule to make target `testing', needed by `files'. Stop.
files目标需要testing目录的存在才能工作。如何告诉make目录可以通过执行target dir来创建?

(在这个简化的例子中,答案是使测试依赖项成为目标dir,而不是硬连接的目录名。)

但在现实中,这些食谱相当长,并且做了大量其他工作(例如从XML文档中提取元数据),并且使用变量而不是硬编码的文件名。是否有一种方法告诉make一个特定的文件名或目录依赖可以通过执行另一个目标来满足?或者我需要将整个事情分解成原子(基本上每个目标一个shell命令)?

实际上,是否有一种方法可以告诉make目标x创建文件y?这是模式规则可以做到的(的一部分使我从未使用过)吗?

有没有办法告诉make目标x创建文件y

你需要调整你的术语。目标是被创建的东西。配方 (shell命令或其他)创建目标。先决条件是用于创建目标的文件或目标,如果先决条件比目标更新,则需要更新目标(使用配方)。Make将首先将每个先决条件视为递归的目标来考虑,并尝试确保它是最新的。

然后你写你的规则:

<target> : [<prerequisite> [<prerequisite> ...]]
        <recipe>
所以,如果你想写一个规则,从先决条件x创建文件y,你可以这样写:
y : x
        <recipe>

在上面的示例中,您依赖于先决条件testing,但是您没有构建目标testing的规则。你有一个规则,建立目标dir,这是没有帮助的。重写规则:

testing:
        mkdir testing

(尽管这不是处理目录的好方法)。

如果你对makefile中的某个文件夹有依赖,你应该使用order-only-先决条件而不是普通的先决条件。使用order-only-先决条件,文件夹将只创建一次,make将不关心时间戳。

的例子:

all: testing/file1.txt testing/file2.txt
testing:
    @mkdir -p testing
testing/file1.txt: | testing
    <generate testing/file1.txt>
testing/file2.txt: | testing
    <generate testing/file2.txt> 

它认为你总是应该使用make-targets来创建文件夹,特别是当两个或多个目标依赖于一个文件夹时。

最新更新