Instead of having a monolithic 'make install', break it into
multiple targets such as 'make install-man3'. This simplifies
packaging, for example in Debian, where they break this project
into several packages: 'manpages' and 'manpages-dev', each
containing different mandirs.
The above allows for multithread installation: 'make -j'
Also, don't overwrite files that don't need to be overwritten, by
having a target for files, which makes use of make's timestamp
comparison.
This allows for much faster installation times.
For comparison, on my laptop (i7-8850H; 6C/12T):
Old Makefile:
~/src/linux/man-pages$ time sudo make >/dev/null
real 0m7.509s
user 0m5.269s
sys 0m2.614s
The times with the old makefile, varied a lot, between
5 and 10 seconds. The times after applying this patch
are much more consistent. BTW, I compared these times to
the very old Makefile of man-pages-5-09, and those were
around 3.5 s, so it was a bit of my fault to have such a
slow Makefile, when I changed the Makefile some weeks ago.
New Makefile (full clean install):
~/src/linux/man-pages$ time sudo make >/dev/null
real 0m5.160s
user 0m4.326s
sys 0m1.137s
~/src/linux/man-pages$ time sudo make -j2 >/dev/null
real 0m1.602s
user 0m2.529s
sys 0m0.289s
~/src/linux/man-pages$ time sudo make -j >/dev/null
real 0m1.398s
user 0m2.502s
sys 0m0.281s
Here we can see that 'make -j' drops times drastically,
compared to the old monolithic Makefile. Not only that,
but since when we are working with the man pages there
aren't many pages involved, times will be even better.
Here are some times with a single page changed (touched):
New Makefile (one page touched):
~/src/linux/man-pages$ touch man2/membarrier.2
~/src/linux/man-pages$ time sudo make install
- INSTALL /usr/local/share/man/man2/membarrier.2
real 0m0.988s
user 0m0.966s
sys 0m0.025s
~/src/linux/man-pages$ touch man2/membarrier.2
~/src/linux/man-pages$ time sudo make install -j
- INSTALL /usr/local/share/man/man2/membarrier.2
real 0m0.989s
user 0m0.943s
sys 0m0.049s
Also, modify the output of the make install and uninstall commands
so that a line is output for each file or directory that is
installed, similarly to the kernel's Makefile. This doesn't apply
to html targets, which haven't been changed in this commit.
Also, make sure that for each invocation of $(INSTALL_DIR), no
parents are created, (i.e., avoid `mkdir -p` behavior). The GNU
make manual states that it can create race conditions. Instead,
declare as a prerequisite for each directory its parent directory,
and let make resolve the order of creation.
Also, use ':=' instead of '=' to improve performance, by
evaluating each assignment only once.
Ensure than the shell is not called when not needed, by removing
all ";" and quotes in the commands.
See also: <https://stackoverflow.com/q/67862417/6872717>
Specify conventions and rationales used in the Makefile in a comment.
Add copyright.
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
On 5/10/21 7:13 PM, Alejandro Colomar (man-pages) wrote:
> Hi Michael,
>
> On 5/10/21 1:39 AM, Michael Kerrisk (man-pages) wrote:
>>> - Specify shebang
>>
>> Why? It's not quite obvious to me, and the commit message
>> should really explain...
>
> Hmmm. I have some minor reasons to add it, but not a really good one.
>
> * Some editors don't recognize 'Makefile' as a special name, so the
> shebang helps detecting which language the file is using (e.g., for
> coloring).
>
> * I tend to subdivide a big Makefile into a small Makefile and many
> submakefiles stored in <./libexec/>. Those obviously need different
> names, and given that the makefile extension is not very standard (I use
> .mk), having a shebang helps knowing what the file is. After that, I
> also have it on the main Makefile for consistency. But here we only
> have one Makefile, so it doesn apply very much.
I think I'll remove it. It is kind of idiosyncratic, leaves the
reader asking "why?".
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Prerequisites can run in parallel. This wouldn't make any sense
when uninstalling and installing again.
For that, use consecutive commands, which run one after the other
even with multiple cores.
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
IMPORTANT for distributions:
This changes prefix to be '/usr/local' as is expected by default,
instead of the old '/usr' value.
- Use standard variables:
- prefix should be '/usr/local'
- mandir (instead of MANDIR)
- htmldir (instead of HTDIR)
- ...
see <https://www.gnu.org/software/make/manual/html_node/Directory-Variables.html>
- Use standard targets:
- html (build html files; don't install them)
- install-html (instead of html)
- installdirs (instead of 'mkdir -p'/'install -d' inside other targets)
- ...
see <https://www.gnu.org/software/make/manual/html_node/Standard-Targets.html#Standard-Targets>
- Use .PHONY
- ?= is not needed. User input overrides any assignment. Use =
- Use standard command variables, instead of directly calling commands.
- $(INSTALL_DATA) (instead of install -m 644)
- $(INSTALL_DIR) (instead of install -d -m 755 or mkdir -p)
see <https://www.gnu.org/software/make/manual/html_node/Command-Variables.html#Command-Variables>
- Specify SHELL = /bin/bash
- Specify shebang
- Allow variable html extension (or no extension at all)
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
mkdir -p doesn't fail if the directory already exists.
Remove redundant checks.
Use .html as default HTDIR.
Remove checks for undefined HTDIR.
Show what the target does, as with other targets (remove '@').
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Switching into the man? subdirectories when running man2html(1)
caused a bug where ".so dir/page.n" links were misinterpreted
(because the directory prefix was interpreted with respect to
the current directory)i, and consequently, the link files
were not correctly rendered. There's no need to switch into the
subdirectories.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Compression is already handled properly by distros and
explicit support from the package is not desired nowadays.
The 'screen' target doesn't handle compressed files.
Removal suggested by Mike Frysinger.
Signed-off-by: Alexander Miller <alex.miller@gmx.de>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
* Fix race condition (don't remove and re-create $GROFF_LOG repeatedly),
* check for failure to create $GROFF_LOG,
* use $TMPDIR if set instead of hardcoded "/tmp",
* quote variables,
* use clobbering redirection (just in case),
* don't create unnecessary subshells,
* add a semicolon for consistency.
Signed-off-by: Alexander Miller <alex.miller@gmx.de>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Convert "GROFF_LOG" into a shell variable local to the
recipe for "check-groff-warnings" target such that the
temporary file is only created when needed.
Acked-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Alexander Miller <alex.miller@gmx.de>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Add a 'check-groff-warnings' target to check if groff
reports warnings (the underlying problem may be causing
words or sentences not to be displayed) from
http://lintian.debian.org/tags/manpage-has-errors-from-man.html
Some edits by mtk.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
For some casual readers of the Makefile, "mkdir -p" is
probably a little easier to read than the equivalent "-make".
Reported-by: Reuben Thomas <rrt@sc3d.org>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
"uninstall" is the GNU standard name for the target,
so it'll be the one most users are used to.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>