Sphinx的默认Makefile

时间:2017-05-14 18:42:09

标签: makefile python-sphinx

我试图了解sphinx-quickstart自动生成的Makefile。这是:

SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
SPHINXPROJ    = myproj
SOURCEDIR     = source
BUILDDIR      = build

.PHONY: help Makefile

%: Makefile
    @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

令我困惑的是:

.PHONY: help Makefile
%: Makefile

我想我明白了:

  1. %目标意味着捕获任何内容(通配符)。例如,如果我输入make html,则%会抓取html
  2. .PHONY Makefile表示make不应在其目录中查找名为Makefile的文件,因此,不应检查文件的修改时间确定是否运行规则。
  3. 我不明白:

    为什么Makefile被列为目标%的先决条件。我解释这个的方式是:

    %捕获的目标规则应在Makefile更改时运行。

    但这在上下文中没有任何意义。我期望的是:

    %捕获的目标规则应在项目文档的源文件或API源文件发生更改时运行。

    目录结构

    .
    ├── build
    ├── Makefile
    ├── source
    └── utils
    

1 个答案:

答案 0 :(得分:2)

.PHONY: foo的效果是foo永远不会被认为是最新的。 (但请参阅https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html以获取更详细的解释:主要用途是针对非文件名的目标)

如果您有bar: foo,则bar目标的规则将始终在make bar上执行,因为目标取决于foo,但foo被视为bar永远不会是最新的。这也可以通过将%目标声明为PHONY本身来实现。

catch-all html目标的问题在于Makefile所在的库存包含一个库或与Sphinx构建器同名的文件。比如说Makefile所在的库中有manmake html:如果%没有依赖关系,则html将不会执行任何操作,因为{{1}然后是一个没有依赖关系的文件或库,因此永远不会得到更新。

因此%依赖于Makefile伪目标,Makefile本身声明为PHONY,因此它被认为永远不会是最新的。(*)即使汇编包含文件html然后make html将被执行(并且修改了构建目录中的html库;不会修改Makefile库中的html

(*)编辑:我忘记了确切的细节:Makefile始终被视为目标,请参阅a surprising (?) behaviour of GNU Make when using ``%`` as target。由于这里解释的原因,%依赖于Makefile,并且Makefile实际上被宣布为PHONY,以避免抱怨循环依赖......

这个想法是Makefile不应该包含所有可能的构建器的硬编码列表:否则它们可能已被单独声明为PHONY目标,但是然后Sphinx维护者将不得不担心Makefile模板保持最新添加新构建器时。当项目保持相同的Makefile但是新的Sphinx版本添加了新的构建器时,它也会导致问题。

如果将新的构建器添加到Sphinx,则不必修改sphinx-quickstart现在创建的Makefile。当然可以肯定,Makefile永远不会成为建造者的名字......