Reputation: 2668
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
%
target means capture anything (wildcard). E.g., if I typed make html
, %
would capture html
..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.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.
.
├── build
├── Makefile
├── source
└── utils
Upvotes: 8
Views: 4361
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