• Alejandro Colomar's avatar
    Makefile, README: Break installation into a target for each mandir · 336ae0d2
    Alejandro Colomar authored
    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: default avatarAlejandro Colomar <alx.manpages@gmail.com>
    Signed-off-by: default avatarMichael Kerrisk <mtk.manpages@gmail.com>
    336ae0d2