Filip Kilibarda
Filip Kilibarda

Reputation: 2668

Default Makefile for Sphinx

I'm trying to understand the Makefile that is automatically produced by sphinx-quickstart. Here it is:

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

.PHONY: help Makefile

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

The lines that confuse me are:

.PHONY: help Makefile
%: Makefile

I think I understand:

  1. The % target means capture anything (wildcard). E.g., if I typed make html, % would capture html.
  2. .PHONY Makefile means that make shouldn't look for a file called Makefile in its directory, thus, shouldn't check the file's modified time to determine whether or not to run a rule.

I don't understand:

Why Makefile is listed as a prerequisite for the target %. The way I interpret this is:

The target rule captured by % should run when the Makefile is changed.

But that doesn't make any sense in the context. What I would expect is:

The target rule captured by % should run when the source files for the project documentation or the API source files have changed.

Directory structure

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

Upvotes: 8

Views: 4361

Answers (1)

user4184837
user4184837

Reputation:

The .PHONY: foo has the effect that foo is never to be considered up-to-date. (but see https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html for the more detailed explanations: the main use is for targets which are not filenames)

If you then have bar: foo, the rules for bar target will always be executed on make bar because the target depends upon foo but foo is considered never up-to-date. This can also be achieved with declaring bar target to be PHONY itself.

The problem with the catch-all % target was in case the repertory where the Makefile is located contained a repertory or a file having same name as a Sphinx builder. Say for example there is an html or a man in repertory where Makefile is located: then make html will not do anything if % has no dependencies, because html is then a file or repertory with no dependencies, hence never to get updated.

Thus the % was made to depend on Makefile pseudo target, and Makefile itself declared PHONY so that it is considered never up-to-date.(*) Even if repertory contains a file html then make html will get executed (and html repertory in build dir modified; the html in Makefile repertory will not be modified).

(*) edit: I had forgotten the exact details: Makefile is always considered a target, see a surprising (?) behaviour of GNU Make when using ``%`` as target. For reasons explained here % was made to depend upon Makefile, and the Makefile was declared PHONY in fact to avoid make complaining about circular dependency...

The idea is that the Makefile should not contain the hard-coded list of all possible builders: else they could have been declared PHONY targets individually, but then Sphinx maintainers would have to worry about keeping the Makefile template up-to-date when adding a new builder. It would also cause problems when projects keep same Makefile but a new Sphinx release adds a new builder.

The Makefile now created by sphinx-quickstart does not have to be modified if a new builder is added to Sphinx. It is of course certain that never will Makefile be the name of a builder...

Upvotes: 6

Related Questions