Sphinx 的默认 Makefile
Default Makefile for 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
我想我明白了:
%
目标表示捕获任何内容(通配符)。例如,如果我键入 make html
,%
将捕获 html
。
.PHONY Makefile
意味着 make
不应该在其目录中查找名为 Makefile
的文件,因此,不应该检查文件的修改时间来确定是否运行 一条规则。
我不明白:
为什么 Makefile
被列为目标 %
的先决条件。我对此的解释是:
当Makefile
改变时,%
捕获的目标规则应该运行。
但这在上下文中没有任何意义。我期望的是:
当项目文档的源文件或API源文件发生变化时,%
捕获的目标规则应该运行。
目录结构
.
├── build
├── Makefile
├── source
└── utils
.PHONY: foo
的效果是 foo
永远不会被认为是最新的。 (但请参阅 https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html 了解更详细的解释:主要用于非文件名的目标)
如果你有 bar: foo
,bar
目标的规则将始终在 make bar
上执行,因为目标取决于 foo
但 foo
被认为永远不会是最新的。这也可以通过将 bar
目标声明为 PHONY 本身来实现。
万能 %
目标的问题是万一 Makefile 所在的目录包含一个目录或与 Sphinx 构建器同名的文件。例如,在 Makefile 所在的目录中有一个 html
或一个 man
:如果 %
没有依赖项,那么 make html
将不会执行任何操作,因为 html
是一个没有依赖关系的文件或目录,因此永远不会更新。
因此 %
依赖于 Makefile 伪目标,并且 Makefile 本身声明为 PHONY,因此它被认为永远不会是最新的。(*) 即使 repertory 包含一个文件 html
然后 make html
将被执行(并且构建目录中的 html
目录已修改;Makefile 目录中的 html
将不会被修改)。
(*) 编辑:我忘记了确切的细节:Makefile 始终被视为目标,请参阅 。出于此处解释的原因,%
依赖于 Makefile,实际上 Makefile 被声明为 PHONY 以避免 make 抱怨循环依赖...
这个想法是 Makefile 不应该包含所有可能的构建器的硬编码列表:否则它们可能被单独声明为 PHONY 目标,但是 Sphinx 维护者将不得不担心保持 Makefile 模板最新- 添加新构建器时的日期。当项目保持相同的 Makefile 但新的 Sphinx 版本添加了新的构建器时,它也会导致问题。
如果将新的构建器添加到 Sphinx,则无需修改现在由 sphinx-quickstart 创建的 Makefile。当然可以肯定的是,Makefile
永远不会成为建造者的名字...
我试图了解 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
我想我明白了:
%
目标表示捕获任何内容(通配符)。例如,如果我键入make html
,%
将捕获html
。.PHONY Makefile
意味着make
不应该在其目录中查找名为Makefile
的文件,因此,不应该检查文件的修改时间来确定是否运行 一条规则。
我不明白:
为什么 Makefile
被列为目标 %
的先决条件。我对此的解释是:
当Makefile
改变时,%
捕获的目标规则应该运行。
但这在上下文中没有任何意义。我期望的是:
当项目文档的源文件或API源文件发生变化时,%
捕获的目标规则应该运行。
目录结构
.
├── build
├── Makefile
├── source
└── utils
.PHONY: foo
的效果是 foo
永远不会被认为是最新的。 (但请参阅 https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html 了解更详细的解释:主要用于非文件名的目标)
如果你有 bar: foo
,bar
目标的规则将始终在 make bar
上执行,因为目标取决于 foo
但 foo
被认为永远不会是最新的。这也可以通过将 bar
目标声明为 PHONY 本身来实现。
万能 %
目标的问题是万一 Makefile 所在的目录包含一个目录或与 Sphinx 构建器同名的文件。例如,在 Makefile 所在的目录中有一个 html
或一个 man
:如果 %
没有依赖项,那么 make html
将不会执行任何操作,因为 html
是一个没有依赖关系的文件或目录,因此永远不会更新。
因此 %
依赖于 Makefile 伪目标,并且 Makefile 本身声明为 PHONY,因此它被认为永远不会是最新的。(*) 即使 repertory 包含一个文件 html
然后 make html
将被执行(并且构建目录中的 html
目录已修改;Makefile 目录中的 html
将不会被修改)。
(*) 编辑:我忘记了确切的细节:Makefile 始终被视为目标,请参阅 %
依赖于 Makefile,实际上 Makefile 被声明为 PHONY 以避免 make 抱怨循环依赖...
这个想法是 Makefile 不应该包含所有可能的构建器的硬编码列表:否则它们可能被单独声明为 PHONY 目标,但是 Sphinx 维护者将不得不担心保持 Makefile 模板最新- 添加新构建器时的日期。当项目保持相同的 Makefile 但新的 Sphinx 版本添加了新的构建器时,它也会导致问题。
如果将新的构建器添加到 Sphinx,则无需修改现在由 sphinx-quickstart 创建的 Makefile。当然可以肯定的是,Makefile
永远不会成为建造者的名字...