summaryrefslogblamecommitdiffstats
path: root/Makefile
blob: 0da0328d879c0751b4181d2c4b22e9e7ce51637a (plain) (tree)


























                                                                              
                                 








































                                       
 




                                         
 
                               
 

           
    





























































































































                                                                                
 
          
                            
                                                         































                                                                                   






                                                                  


                                                                        
 
                                                                           
                                                         
                            
                     
                                                                          

                                





                                                                                                                        
 

                                                               



                                                                        
########################################################################
# Copyright (C) 2021        Alejandro Colomar <alx.manpages@gmail.com>
# SPDX-License-Identifier:  GPL-2.0  OR  LGPL-2.0
########################################################################
# Conventions:
#
# - Follow "Makefile Conventions" from the "GNU Coding Standards" closely.
#   However, when something could be improved, don't follow those.
# - Uppercase variables, when referring files, refer to files in this repo.
# - Lowercase variables, when referring files, refer to system files.
# - Variables starting with '_' refer to absolute paths, including $(DESTDIR).
# - Variables ending with '_' refer to a subdir of their parent dir, which
#   is in a variable of the same name but without the '_'.  The subdir is
#   named after this project: <*/man>.
# - Variables ending in '_rm' refer to files that can be removed (exist).
# - Variables ending in '_rmdir' refer to dirs that can be removed (exist).
# - Targets of the form '%-rm' remove their corresponding file '%'.
# - Targets of the form '%/.-rmdir' remove their corresponding dir '%/'.
# - Targets of the form '%/.' create their corresponding directory '%/'.
# - Every file or directory to be created depends on its parent directory.
#   This avoids race conditions caused by `mkdir -p`.  Only the root
#   directories are created with parents.
# - The 'FORCE' target is used to make phony some variables that can't be
#   .PHONY to avoid some optimizations.
#
########################################################################

MAKEFLAGS += --no-print-directory
MAKEFLAGS += --silent
MAKEFLAGS += --warn-undefined-variables


htmlbuilddir := $(CURDIR)/.html
HTOPTS :=

DESTDIR :=
prefix := /usr/local
datarootdir := $(prefix)/share
docdir := $(datarootdir)/doc
MANDIR := $(CURDIR)
mandir := $(datarootdir)/man
MAN1DIR := $(MANDIR)/man1
MAN2DIR := $(MANDIR)/man2
MAN3DIR := $(MANDIR)/man3
MAN4DIR := $(MANDIR)/man4
MAN5DIR := $(MANDIR)/man5
MAN6DIR := $(MANDIR)/man6
MAN7DIR := $(MANDIR)/man7
MAN8DIR := $(MANDIR)/man8
man1dir := $(mandir)/man1
man2dir := $(mandir)/man2
man3dir := $(mandir)/man3
man4dir := $(mandir)/man4
man5dir := $(mandir)/man5
man6dir := $(mandir)/man6
man7dir := $(mandir)/man7
man8dir := $(mandir)/man8
manext := \.[0-9]
man1ext := .1
man2ext := .2
man3ext := .3
man4ext := .4
man5ext := .5
man6ext := .6
man7ext := .7
man8ext := .8
htmldir := $(docdir)
htmldir_ := $(htmldir)/man
htmlext := .html

INSTALL := install
INSTALL_DATA := $(INSTALL) -m 644
INSTALL_DIR := $(INSTALL) -m 755 -d
RM := rm
RMDIR := rmdir --ignore-fail-on-non-empty

MAN_SECTIONS := 1 2 3 4 5 6 7 8


.PHONY: all
all:
	$(MAKE) uninstall
	$(MAKE) install


%/.:
	$(info -	INSTALL	$(@D))
	$(INSTALL_DIR) $(@D)

%-rm:
	$(info -	RM	$*)
	$(RM) $*

%-rmdir:
	$(info -	RMDIR	$(@D))
	$(RMDIR) $(@D)


.PHONY: install
install: install-man | installdirs
	@:

.PHONY: installdirs
installdirs: | installdirs-man
	@:

.PHONY: uninstall remove
uninstall remove: uninstall-man
	@:

.PHONY: clean
clean:
	find man?/ -type f \
	|while read f; do \
		rm -f "$(htmlbuilddir)/$$f".*; \
	done;

########################################################################
# man

MANPAGES   := $(sort $(shell find $(MANDIR)/man?/ -type f | grep '$(manext)$$'))
_manpages  := $(patsubst $(MANDIR)/%,$(DESTDIR)$(mandir)/%,$(MANPAGES))
_man1pages := $(filter %$(man1ext),$(_manpages))
_man2pages := $(filter %$(man2ext),$(_manpages))
_man3pages := $(filter %$(man3ext),$(_manpages))
_man4pages := $(filter %$(man4ext),$(_manpages))
_man5pages := $(filter %$(man5ext),$(_manpages))
_man6pages := $(filter %$(man6ext),$(_manpages))
_man7pages := $(filter %$(man7ext),$(_manpages))
_man8pages := $(filter %$(man8ext),$(_manpages))

MANDIRS  := $(sort $(shell find $(MANDIR)/man? -type d))
_mandirs := $(patsubst $(MANDIR)/%,$(DESTDIR)$(mandir)/%/.,$(MANDIRS))
_man1dir := $(filter %man1/.,$(_mandirs))
_man2dir := $(filter %man2/.,$(_mandirs))
_man3dir := $(filter %man3/.,$(_mandirs))
_man4dir := $(filter %man4/.,$(_mandirs))
_man5dir := $(filter %man5/.,$(_mandirs))
_man6dir := $(filter %man6/.,$(_mandirs))
_man7dir := $(filter %man7/.,$(_mandirs))
_man8dir := $(filter %man8/.,$(_mandirs))
_mandir  := $(DESTDIR)$(mandir)/.

_manpages_rm  := $(addsuffix -rm,$(wildcard $(_manpages)))
_man1pages_rm := $(filter %$(man1ext)-rm,$(_manpages_rm))
_man2pages_rm := $(filter %$(man2ext)-rm,$(_manpages_rm))
_man3pages_rm := $(filter %$(man3ext)-rm,$(_manpages_rm))
_man4pages_rm := $(filter %$(man4ext)-rm,$(_manpages_rm))
_man5pages_rm := $(filter %$(man5ext)-rm,$(_manpages_rm))
_man6pages_rm := $(filter %$(man6ext)-rm,$(_manpages_rm))
_man7pages_rm := $(filter %$(man7ext)-rm,$(_manpages_rm))
_man8pages_rm := $(filter %$(man8ext)-rm,$(_manpages_rm))

_mandirs_rmdir := $(addsuffix -rmdir,$(wildcard $(_mandirs)))
_man1dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man1dir)))
_man2dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man2dir)))
_man3dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man3dir)))
_man4dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man4dir)))
_man5dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man5dir)))
_man6dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man6dir)))
_man7dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man7dir)))
_man8dir_rmdir := $(addsuffix -rmdir,$(wildcard $(_man8dir)))
_mandir_rmdir  := $(addsuffix -rmdir,$(wildcard $(_mandir)))

install_manX     := $(foreach x,$(MAN_SECTIONS),install-man$(x))
installdirs_manX := $(foreach x,$(MAN_SECTIONS),installdirs-man$(x))
uninstall_manX   := $(foreach x,$(MAN_SECTIONS),uninstall-man$(x))


.SECONDEXPANSION:
$(_manpages): $(DESTDIR)$(mandir)/man%: $(MANDIR)/man% | $$(@D)/.
	$(info -	INSTALL	$@)
	$(INSTALL_DATA) -T $< $@

$(_mandirs): %/.: | $$(dir %). $(_mandir)

$(_mandirs_rmdir): $(DESTDIR)$(mandir)/man%/.-rmdir: $$(_man%pages_rm) FORCE
$(_mandir_rmdir): $(uninstall_manX) FORCE


.PHONY: $(install_manX)
$(install_manX): install-man%: $$(_man%pages) | installdirs-man%
	@:

.PHONY: install-man
install-man: $(install_manX)
	@:

.PHONY: $(installdirs_manX)
$(installdirs_manX): installdirs-man%: $$(_man%dir) $(_mandir)
	@:

.PHONY: installdirs-man
installdirs-man: $(installdirs_manX)
	@:

.PHONY: $(uninstall_manX)
$(uninstall_manX): uninstall-man%: $$(_man%pages_rm) $$(_man%dir_rmdir)
	@:

.PHONY: uninstall-man
uninstall-man: $(_mandir_rmdir) $(uninstall_manX)
	@:


########################################################################
# html

# Use with
#  make HTOPTS=whatever html
# The sed removes the lines "Content-type: text/html\n\n"
.PHONY: html
html: | builddirs-html
	find man?/ -type f \
	|while read f; do \
		man2html $(HTOPTS) "$$f" \
		|sed -e '1,2d' \
		>"$(htmlbuilddir)/$${f}$(htmlext)" \
			|| exit $$?; \
	done;

.PHONY: builddirs-html
builddirs-html:
	find man?/ -type d \
	|while read d; do \
		$(INSTALL_DIR) "$(htmlbuilddir)/$$d" || exit $$?; \
	done;

.PHONY: install-html
install-html: | installdirs-html
	cd $(htmlbuilddir) && \
	find man?/ -type f \
	|while read f; do \
		$(INSTALL_DATA) -T "$$f" "$(DESTDIR)$(htmldir_)/$$f" || exit $$?; \
	done;

.PHONY: installdirs-html
installdirs-html:
	find man?/ -type d \
	|while read d; do \
		$(INSTALL_DIR) "$(DESTDIR)$(htmldir_)/$$d" || exit $$?; \
	done;

.PHONY: uninstall-html
uninstall-html:
	find man?/ -type f \
	|while read f; do \
		rm -f "$(DESTDIR)$(htmldir_)/$$f".* || exit $$?; \
	done;


########################################################################
# tests

# Check if groff reports warnings (may be words of sentences not displayed)
# from https://lintian.debian.org/tags/groff-message.html
.PHONY: check-groff-warnings
check-groff-warnings:
	GROFF_LOG="$$(mktemp --tmpdir manpages-checksXXXX)" || exit $$?; \
	for i in man?/*.[1-9]; \
	do \
		if grep -q 'SH.*NAME' "$$i"; then \
			LC_ALL=en_US.UTF-8 MANWIDTH=80 man --warnings -E UTF-8 -l "$$i" > /dev/null 2>| "$$GROFF_LOG"; \
			[ -s "$$GROFF_LOG" ] && { echo "$$i: "; cat "$$GROFF_LOG"; echo; }; \
		fi; \
	done; \
	rm -f "$$GROFF_LOG"

# someone might also want to look at /var/catman/cat2 or so ...
# a problem is that the location of cat pages varies a lot

########################################################################

FORCE: