From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB3E2C47094 for ; Mon, 7 Jun 2021 21:36:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A949C6120F for ; Mon, 7 Jun 2021 21:36:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230411AbhFGViU (ORCPT ); Mon, 7 Jun 2021 17:38:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34778 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230359AbhFGViU (ORCPT ); Mon, 7 Jun 2021 17:38:20 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 108E9C061574 for ; Mon, 7 Jun 2021 14:36:14 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id r9so2514438wrz.10 for ; Mon, 07 Jun 2021 14:36:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bMy4qAJ/BM4vW07VL0iv+SYLZM7yov03tm5kegokpec=; b=PWWhpCJ9r+gShW2BOHXOSWOwIlLvafEehIUmGkv2gXHdd1YfwkGYqc6uOvdCT1fGaJ vmEHfTk1+yEFQEy/H3vrGotF7ueAA3GnYfTV8PdiqW3OH3vX3Rmr5opVweP7h6RJGEi2 9QHw6p3+AbWwERymjCMX+nANi5KroEmPWj93leL3lpR3Er94HBvEtc0BiAu7Zz+fOvYy k0tkxOpq+0g+LGxVDIp/dVDykkV1TnIeqFUclxNERG9mUTbn5pfSGughq5h/3+HfW7lq Z9q6W8i6W63Yw+5ad/EGV+cbxUK+nViMznY+iJAOvQlENHRSruJpZdPdxUDTppD6gmfu 01Iw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bMy4qAJ/BM4vW07VL0iv+SYLZM7yov03tm5kegokpec=; b=S4REupPTi3zAGSEyQ9dAdEsUiqgQVd2/PCTO40v4a6zbDWAcfOv3g/fx8VUb13MjKC ngyKzngO8Ej4cJCkt8Cgr93cmLpF9GKAYyk8XCoGxM3T4mDbN4bS+Iy1hN+vUa/bGJ5u uEmxtHWDjsY5vUdFz7YxsFZDNFMLL4rqDPiDr8L7xUL9xaz318Vpz1LhmXZqt47+Bp6T 2okn4sLmh7R8hGjfIUMLDnslq+NpeNUEVky8tStjsxacXuVvmJ7XlMVwD2EJuko5Bj8p vnesBNIiJ8vt0AFgGjTQtWzBu+YkWUmnTrAq2HDcaRoy+OXq4e4TNCmDhncHfeeORGsB yj4w== X-Gm-Message-State: AOAM533w6ehQXXkXIDWbAN9YfMb4KGuzslkYlGrcsn+2KKIq3H21RFSi d1a+Mfsu6H5ZG96h+M6R/c8= X-Google-Smtp-Source: ABdhPJyTCynBsinj75zF3xuukK6RSdCKPxkz5j5ZZr9LPu2X444QQBXoj8dPjWxI7mBOex/rtI2SBg== X-Received: by 2002:adf:f346:: with SMTP id e6mr18631401wrp.179.1623101772535; Mon, 07 Jun 2021 14:36:12 -0700 (PDT) Received: from sqli.sqli.com ([195.53.121.100]) by smtp.googlemail.com with ESMTPSA id q3sm17818724wrz.71.2021.06.07.14.36.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 14:36:12 -0700 (PDT) From: Alejandro Colomar To: mtk.manpages@gmail.com Cc: Alejandro Colomar , linux-man@vger.kernel.org, "Dr . Tobias Quathamer" Subject: [PATCH v22] Makefile, README: Break installation into a target for each mandir Date: Mon, 7 Jun 2021 23:36:09 +0200 Message-Id: <20210607213609.90785-1-alx.manpages@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210604205319.154059-1-alx.manpages@gmail.com> References: <20210604205319.154059-1-alx.manpages@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-man@vger.kernel.org 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 containinng different mandirs. The above allows for multithread installation: 'make -j8' 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.072s user 0m4.356s sys 0m0.980s ~/src/linux/man-pages$ time sudo make -j2 >/dev/null real 0m1.688s user 0m2.616s sys 0m0.283s ~/src/linux/man-pages$ time sudo make -j >/dev/null real 0m1.468s user 0m2.579s sys 0m0.289s 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.976s user 0m0.952s sys 0m0.027s ~/src/linux/man-pages$ touch man2/membarrier.2 ~/src/linux/man-pages$ time sudo make -j install - INSTALL /usr/local/share/man/man2/membarrier.2 real 0m0.967s user 0m0.964s sys 0m0.007s 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 invokation 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: Signed-off-by: Alejandro Colomar --- v2: - Revert changes to 'make [all]', as it might break existing scripts. v3: - Remove unnecessary target installdirs (its functionality has been superseeded by installdirs-man). v4: - srcfix v5: - wsfix - Remove duplicate echo v6: - Add paragraph to commit msg. v7: - Output which files are removed (one RM line for each file) - Add manext variable, to avoid repeating the \.[0-9] regex. - Don't use ?=. It's ugly, and makes no tangible effects (I tested that the times are the same). v8: - wsfix - Replace small shell scripts by proper Makefile dependencies and helper targets. v9: - wsfix - Sort files, so that the installation is more predictable, and thus, one can guess the progress of the install by the filenames in the log. v10: - srcfix: use patsubst instead of addprefix + notdir, to be more clear. v11: - Reorder things a bit to make it easier to read. - Remove an unnecessary dependency. v12: - tfix v13: - Remove unused variable: manext - Define undefined variables: man[1-8]ext - A few minor srcfix - Add times comparison and output examples to commit msg. v14: - Replace '=' with ':=' to improve performance. Times in commit msg updated for this change. - Add a note in the README that installation should use multiple threads for performance reasons. v15: - Move some code into variables (times didn't change considerably). v16: - Add missing .PHONY: $(uninstall_manpages) v17: - Replace *_MANN by *_MANn, which is more readable. v18: - Don't use bash(1). We don't need pipefail now that I simplified the targets to have simple separate commands. make(1) will now break installation if anything fails. This cut times by around 40%. - Don't call echo(1). Invoking a shell just to call echo(1) for every file is too expensive. Use make(1)'s $(info ...) function. This cut times by another 40%. - Update the commit msg to reflect the times after these changes. For a single thread, it's using around a third of the time that v17 needed. - v18 applies on top of mtk's tree, unlike previous revisions, which applied on top of another patch of mine, which I dropped. v19: - Remove `;` and `'` to avoid calling unnecessary shells. - The above improved performance by another 50% or so; update the commit msg with the new times. - Fix some dependencies. - Add installdirs again. - srcfix: reduce LOC v20: - Workaround a bug in make 3.81 where a trailing slash is ignored. See That helps workaround some ambiguity in the rules, wher a rule to uninstall a dir also matched the pattern rule to install that dir. v21: - ffix v22: - Avoid race conditions, by avoiding `mkdir -p` behavior. - Reduce LOCs by using make's `$(foreach ...)` and `.SECONDEXPANSION:`. - Add an empty recipe for each target that does nothing but declare dependencies, to avoid implicit rules. Makefile | 203 +++++++++++++++++++++++++++++++++++++++++++------------ README | 8 +++ 2 files changed, 167 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 609009715..b5ff7e237 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,166 @@ -# Do not print "Entering directory ..." MAKEFLAGS += --no-print-directory +MAKEFLAGS += --silent -htmlbuilddir = $(CURDIR)/.html -HTOPTS = +ROOTDIR := $(CURDIR) +htmlbuilddir := $(ROOTDIR)/.html +HTOPTS := -DESTDIR = -prefix = /usr/local -datarootdir = $(prefix)/share -docdir = $(datarootdir)/doc -mandir = $(datarootdir)/man -htmldir = $(docdir) -htmldir_ = $(htmldir)/man -htmlext = .html +DESTDIR := +prefix := /usr/local +datarootdir := $(prefix)/share +docdir := $(datarootdir)/doc +MANDIR := $(ROOTDIR) +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 -f +RMDIR := rmdir --ignore-fail-on-non-empty + +MAN_SECTIONS := 1 2 3 4 5 6 7 8 -INSTALL = install -INSTALL_DATA = $(INSTALL) -m 644 -INSTALL_DIR = $(INSTALL) -m 755 -d .PHONY: all all: - $(MAKE) uninstall; - $(MAKE) install; + $(MAKE) uninstall + $(MAKE) install + + +%/.: $(dir %). + $(info - INSTALL $*/) + $(INSTALL_DIR) $*/ + + +.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 := $(shell find $(MANDIR)/man?/ -type f | grep '$(manext)$$' | sort) +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)) + +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)) + +.SECONDEXPANSION: +$(manpages): $(DESTDIR)$(mandir)/%: $(MANDIR)/% | $$(@D)/. + $(info - INSTALL $@) + $(INSTALL_DATA) -T $(MANDIR)/$* $@ + + +INSTALL_MANn := $(foreach i,$(MAN_SECTIONS),install-man$(i)) + +.PHONY: $(INSTALL_MANn) +$(INSTALL_MANn): install-%: $$(%pages) | installdirs-% + @: + +.PHONY: install-man +install-man: $(INSTALL_MANn) + @: + + +INSTALLDIRS_MANn := $(foreach i,$(MAN_SECTIONS),installdirs-man$(i)) + +.PHONY: $(INSTALLDIRS_MANn) +$(INSTALLDIRS_MANn): installdirs-%: $(DESTDIR)$(mandir)/%/. | $(DESTDIR)$(mandir)/. + @: + +.PHONY: installdirs-man +installdirs-man: $(INSTALL_MANn) + @: + + +uninstall_manpages := $(addprefix uninstall-,$(wildcard $(manpages))) +uninstall_man1pages := $(filter %$(man1ext),$(uninstall_manpages)) +uninstall_man2pages := $(filter %$(man2ext),$(uninstall_manpages)) +uninstall_man3pages := $(filter %$(man3ext),$(uninstall_manpages)) +uninstall_man4pages := $(filter %$(man4ext),$(uninstall_manpages)) +uninstall_man5pages := $(filter %$(man5ext),$(uninstall_manpages)) +uninstall_man6pages := $(filter %$(man6ext),$(uninstall_manpages)) +uninstall_man7pages := $(filter %$(man7ext),$(uninstall_manpages)) +uninstall_man8pages := $(filter %$(man8ext),$(uninstall_manpages)) + +.PHONY: $(uninstall_manpages) +$(uninstall_manpages): uninstall-%: + $(info - RM $*) + $(RM) $* + + +UNINSTALL_MANn := $(foreach i,$(MAN_SECTIONS),uninstall-man$(i)) + +.PHONY: $(UNINSTALL_MANn) +$(UNINSTALL_MANn): uninstall-%: $$(uninstall_%pages) + $(info - RMDIR $(DESTDIR)$(mandir)/$*/) + $(RMDIR) $(DESTDIR)$(mandir)/$*/ 2>/dev/null ||: + +.PHONY: uninstall-man +uninstall-man: $(UNINSTALL_MANn) + $(info - RMDIR $(DESTDIR)$(mandir)/) + $(RMDIR) $(DESTDIR)$(mandir)/ ||: + + +################################################################################ +# html # Use with # make HTOPTS=whatever html @@ -57,28 +197,6 @@ installdirs-html: $(INSTALL_DIR) "$(DESTDIR)$(htmldir_)/$$d" || exit $$?; \ done; -.PHONY: install -install: | installdirs - find man?/ -type f \ - |while read f; do \ - $(INSTALL_DATA) -T "$$f" "$(DESTDIR)$(mandir)/$$f" || exit $$?; \ - done; - -.PHONY: installdirs -installdirs: - find man?/ -type d \ - |while read d; do \ - $(INSTALL_DIR) "$(DESTDIR)$(mandir)/$$d" || exit $$?; \ - done; - -.PHONY: uninstall remove -uninstall remove: - find man?/ -type f \ - |while read f; do \ - rm -f "$(DESTDIR)$(mandir)/$$f" || exit $$?; \ - rm -f "$(DESTDIR)$(mandir)/$$f".* || exit $$?; \ - done; - .PHONY: uninstall-html uninstall-html: find man?/ -type f \ @@ -86,12 +204,9 @@ uninstall-html: rm -f "$(DESTDIR)$(htmldir_)/$$f".* || exit $$?; \ done; -.PHONY: clean -clean: - find man?/ -type f \ - |while read f; do \ - rm -f "$(htmlbuilddir)/$$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 diff --git a/README b/README index 6598170c0..484151773 100644 --- a/README +++ b/README @@ -26,9 +26,17 @@ To install to a path different from /usr/local, use distribution from its destination. Use with caution, and remember to use "prefix" if desired, as with the "install" target. +To install only a specific man section (mandir) such as man3, use +"make install-man3". Similar syntax can be used to uninstall a +specific man section, such as man7: "make uninstall-man7". + "make" or "make all" will perform "make uninstall" followed by "make install". +Consider using multiple threads (at least 2) when installing +these man pages, as the Makefile is optimized for multiple threads: +"make -j install". + Copyrights ========== See the 'man-pages-x.y.Announce' file. -- 2.31.1