Makefile Sphinx的默认生成文件
我试图理解由Makefile Sphinx的默认生成文件,makefile,python-sphinx,Makefile,Python Sphinx,我试图理解由sphinx quickstart自动生成的Makefile。这是: SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = myproj SOURCEDIR = source BUILDDIR = build .PHONY: help Makefile %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPH
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
我想我明白了:
%
目标表示捕获任何内容(通配符)。例如,如果我键入makehtml
,%
将捕获html
.PHONY Makefile
意味着make
不应在其目录中查找名为Makefile
的文件,因此,不应检查文件的修改时间以确定是否运行规则Makefile
列为目标%
的先决条件。我的解释是:
%
捕获的目标规则应在生成文件
更改时运行
但这在上下文中没有任何意义。我所期望的是:
当项目文档的源文件或API源文件发生更改时,%
捕获的目标规则应运行
目录结构
.PHONY:foo
的作用是,永远不能将foo
视为最新版本。(但有关更详细的说明,请参见:主要用于非文件名的目标)
如果您有bar:foo
,则bar
目标的规则将始终在make bar
上执行,因为目标依赖于foo
,但foo
被视为从未更新过。这也可以通过声明bar
target本身是假的来实现
catch all%
目标的问题在于Makefile所在的存储库包含存储库或与Sphinx builder同名的文件。例如,假设Makefile所在的存储库中有一个html
或一个man
:那么如果%
没有依赖项,则make html
将不起任何作用,因为html
是一个没有依赖项的文件或存储库,因此永远不会得到更新
因此,%
被设置为依赖于Makefile伪目标,并且Makefile本身被声明为虚假的,因此它被认为永远不会是最新的。(*)即使repertory包含一个文件html
,那么makehtml
也会被执行(编译目录中的html
repertory已修改;Makefile repertory中的html
将不被修改)
(*)编辑:我忘记了确切的细节:Makefile始终被视为目标,请参阅。出于此处解释的原因,%
被设置为依赖于Makefile,事实上,Makefile被声明为虚假的,以避免Makefile抱怨循环依赖性
其想法是,Makefile不应该包含所有可能构建器的硬编码列表:否则它们可能会被单独宣布为虚假目标,但Sphinx维护人员在添加新构建器时将不得不担心使Makefile模板保持最新。当项目保持相同的Makefile但一个新的Sphinx版本添加了一个新的构建器
sphinx quickstart现在创建的Makefile如果向sphinx添加新的生成器,则不必修改。当然,可以肯定的是,
Makefile
永远不会是生成器的名称…感谢您的明确解释,它非常有用。我想补充一点,“Makefile始终被视为目标”仅因为文件本身名为“Makefile”。如果将其重命名为例如“Makefile.test”并运行“make-f Makefile.test”,则目标确实是“Makefile.test”。如果使用catch all targets(如Sphinx的默认Makefile中的目标),请务必记住这一点。在我的示例中,我们是在CI中执行此操作的。通过将目标名称更改为“Makefile*”,解决了此问题。
.
├── build
├── Makefile
├── source
└── utils