* [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config @ 2026-08-03 19:21 DJ Delorie 2026-08-06 14:37 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: DJ Delorie @ 2026-08-03 19:21 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man Signed-off-by: DJ Delorie <dj@redhat.com> --- man/man5/tunables.conf.5 | 132 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 man/man5/tunables.conf.5 diff --git a/man/man5/tunables.conf.5 b/man/man5/tunables.conf.5 new file mode 100644 index 000000000..44b32d40c --- /dev/null +++ b/man/man5/tunables.conf.5 @@ -0,0 +1,132 @@ +.TH tunables.conf 5 (date) "Linux man-pages (unreleased)" +.SH NAME +tunables.conf \- tunables configuration file +.SH SYNOPSIS +.nf +.B /etc/tunables.conf +.fi +.SH DESCRIPTION +Tunables are a feature in the GNU C Library +that allows application authors and distribution maintainers +to alter the runtime library behavior to match their workload. +For a list of supported tunables, +please consult the glibc manual +that corresponds to your installed version of glibc, +or run the following command: +.P +.in +4n +.EX +ld.so \-\-list\-tunables +.EE +.P +The file is parsed by +.BR \%ldconfig (8) +and the results stored in +.IR /etc/ld.so.cache . +The resulting data is read when a new process is created by +.IR ld.so . +.P +Each line in the file +.I /etc/tunables.conf +specifies a tunable, +which is specified with a string of the form +.IB name = value \f[R].\f[] +.P +The syntax allows lines to start with the keyword +.I include +followed by a +.BR \%glob (7) +pattern. +Files matching that pattern will be processed +as if their contents were included at that point. +.P +Each line may include zero or more keywords or symbols at the beginning, +which affect how each tunable affects each processes. +The keywords must be separated by whitespace, +but the symbols need not be. +.TP +.B overridable +.TQ +.B + +Allow the tunable to be overridden by the +.B GLIBC_TUNABLES +environment variable when the process runs +(this is the default). +.TP +.B nonoverridable +.TQ +.B \- +Do not allow the tunable to be overridden by the environment variable. +.TP +.B onlysecure +.TQ +.B @ +The tunable applies only to +.B AT_SECURE +processes, +such as one started from a set-user-ID program, +or one with elevated capabilities. +.TP +.B nonsecure +.TQ +.B $ +The tunable applies only to +.RB non- AT_SECURE +processes (this is the default). +.TP +.B anysecure +.TQ +.B * +The tunable applies to both +.B AT_SECURE +and +.RB non- AT_SECURE +processes. +.P +The file may also contain +.IR filters , +which limit the tunables following it, +up to the end of the file +(or end of the included file, +or start of a new included file) +or a line with only +.B [] +on it. +The syntax is: +.P +.in +4n +.EX +.RI [ filter : pattern ] +.EE +.in +.TP +.B proc +The +.B proc +filter limits the following tunables to processes +whose name matches the pattern. +The pattern may be an absolute path +or just the base name. +.SH FILES +.TP +.I /etc/tunables.conf +.TP +.I /etc/ld.so.cache +cached copy of tunables +.SH EXAMPLES +Example configuration file: +.P +.in +4n +.EX +glibc.malloc.arenas_max=5 +onlysecure glibc.malloc.arenas_max=1 +\-glibc.pthread.rseq=1 +[proc:/bin/bad.program] +\-glibc.pthread.rseq=0 +[proc:some.program] +\-glibc.malloc.mmap_threshold=65536 +.EE +.in +.SH SEE ALSO +.BR ld.so (8), +.BR ldconfig (8) -- 2.47.3 ^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-03 19:21 [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config DJ Delorie @ 2026-08-06 14:37 ` Alejandro Colomar 2026-08-06 15:33 ` DJ Delorie 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-06 14:37 UTC (permalink / raw) To: DJ Delorie; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 1954 bytes --] Hi DJ, > Date: 2026-08-03 15:21:31-0400 > From: DJ Delorie <dj@redhat.com> > > > Signed-off-by: DJ Delorie <dj@redhat.com> A few minor comments below. > > --- > man/man5/tunables.conf.5 | 132 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 132 insertions(+) > create mode 100644 man/man5/tunables.conf.5 > > diff --git a/man/man5/tunables.conf.5 b/man/man5/tunables.conf.5 > new file mode 100644 > index 000000000..44b32d40c > --- /dev/null > +++ b/man/man5/tunables.conf.5 > @@ -0,0 +1,132 @@ [...] > +.P > +The file may also contain > +.IR filters , > +which limit the tunables following it, > +up to the end of the file > +(or end of the included file, > +or start of a new included file) I'd append within the parentheses: , whichever comes first > +or a line with only > +.B [] > +on it. So, this is like an end-all-filters directive, right? I wonder something: Does a filter end previous filters, or do they compound until a [] ends them all? > +The syntax is: > +.P > +.in +4n > +.EX > +.RI [ filter : pattern ] Since '[', ':', and ']' are literal, let's put them in bold. Thus, BI. Have a lovely day! Alex > +.EE > +.in > +.TP > +.B proc > +The > +.B proc > +filter limits the following tunables to processes > +whose name matches the pattern. > +The pattern may be an absolute path > +or just the base name. > +.SH FILES > +.TP > +.I /etc/tunables.conf > +.TP > +.I /etc/ld.so.cache > +cached copy of tunables > +.SH EXAMPLES > +Example configuration file: > +.P > +.in +4n > +.EX > +glibc.malloc.arenas_max=5 > +onlysecure glibc.malloc.arenas_max=1 > +\-glibc.pthread.rseq=1 > +[proc:/bin/bad.program] > +\-glibc.pthread.rseq=0 > +[proc:some.program] > +\-glibc.malloc.mmap_threshold=65536 > +.EE > +.in > +.SH SEE ALSO > +.BR ld.so (8), > +.BR ldconfig (8) > -- > 2.47.3 > > -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-06 14:37 ` Alejandro Colomar @ 2026-08-06 15:33 ` DJ Delorie 2026-08-06 19:14 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: DJ Delorie @ 2026-08-06 15:33 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man Alejandro Colomar <alx@kernel.org> writes: > A few minor comments below. I'll defer a v5 until we finish discussing... >> +The file may also contain >> +.IR filters , >> +which limit the tunables following it, >> +up to the end of the file >> +(or end of the included file, >> +or start of a new included file) > > I'd append within the parentheses: > , whichever comes first "first"? Or "next"? >> +or a line with only >> +.B [] >> +on it. > > So, this is like an end-all-filters directive, right? > > I wonder something: Does a filter end previous filters, or do they > compound until a [] ends them all? There is only ever one filter active at a time. It stops being the active filter when another filter is encountered, or the current file ends, or an include directive. An empty filter spec (i.e. "[]") is a "no filters" filter. It acts as a "new filter" for the purpose of ending the previous filter, but does not specify a new filter, so no new filter is active after that. If you can get that into five words or less, you win ;-) >> +The syntax is: >> +.P >> +.in +4n >> +.EX >> +.RI [ filter : pattern ] > > Since '[', ':', and ']' are literal, let's put them in bold. Thus, BI. Done. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-06 15:33 ` DJ Delorie @ 2026-08-06 19:14 ` Alejandro Colomar 2026-08-06 20:17 ` DJ Delorie 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-06 19:14 UTC (permalink / raw) To: DJ Delorie; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 2294 bytes --] Hi DJ, > Date: 2026-08-06 11:33:47-0400 > From: DJ Delorie <dj@redhat.com> > > Alejandro Colomar <alx@kernel.org> writes: > > A few minor comments below. > > I'll defer a v5 until we finish discussing... Good. :) > >> +The file may also contain > >> +.IR filters , > >> +which limit the tunables following it, > >> +up to the end of the file > >> +(or end of the included file, > >> +or start of a new included file) > > > > I'd append within the parentheses: > > , whichever comes first > > "first"? Or "next"? > > >> +or a line with only > >> +.B [] > >> +on it. > > > > So, this is like an end-all-filters directive, right? > > > > I wonder something: Does a filter end previous filters, or do they > > compound until a [] ends them all? > > There is only ever one filter active at a time. It stops being the > active filter when another filter is encountered, or the current file > ends, or an include directive. An empty filter spec (i.e. "[]") is a "no > filters" filter. It acts as a "new filter" for the purpose of ending > the previous filter, but does not specify a new filter, so no new filter > is active after that. > > If you can get that into five words or less, you win ;-) Hmmmm, let's see. I couldn't do it in five words, but how about this schematic approach? The file may also contain .IR filters , which limit the tunables following it, The effects of a filter are terminated by any of the following: .IP \[bu] 3 The end of the file. .IP \[bu] The end of an included file. .IP \[bu] An .B include directive. .IP \[bu] A new (possibly empty) filter. > > >> +The syntax is: > >> +.P > >> +.in +4n > >> +.EX > >> +.RI [ filter : pattern ] > > > > Since '[', ':', and ']' are literal, let's put them in bold. Thus, BI. > > Done. Since a filter can be empty, we should document that. If we document that 'filter:pattern' is optional, it'd be [[filter:pattern]] (with the appropriate formatting differences: the inner '[' wouldn't be bold). However, that's likely to be confusing, so let's document that separately: A filter can also be empty: .BR [] . Such a filter has no effects. Have a lovely day! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-06 19:14 ` Alejandro Colomar @ 2026-08-06 20:17 ` DJ Delorie 2026-08-06 20:31 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: DJ Delorie @ 2026-08-06 20:17 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man Alejandro Colomar <alx@kernel.org> writes: > Hmmmm, let's see. I couldn't do it in five words, but how about this > schematic approach? > > The file may also contain > .IR filters , > which limit the tunables following it, > The effects of a filter are terminated by > any of the following: > .IP \[bu] 3 > The end of the file. > .IP \[bu] > The end of an included file. > .IP \[bu] > An > .B include > directive. > .IP \[bu] > A new (possibly empty) filter. I like it as-is, other than "why are there blank lines" but I don't care about that ;-) > Since a filter can be empty, we should document that. If we document > that 'filter:pattern' is optional, it'd be [[filter:pattern]] (with the > appropriate formatting differences: the inner '[' wouldn't be bold). > However, that's likely to be confusing, so let's document that > separately: > > A filter can also be empty: > .BR [] . > Such a filter has no effects. Done. I put it after the filter list, so the "also" made sense. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-06 20:17 ` DJ Delorie @ 2026-08-06 20:31 ` Alejandro Colomar 2026-08-06 20:42 ` DJ Delorie 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-06 20:31 UTC (permalink / raw) To: DJ Delorie; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 1711 bytes --] Hi DJ, > Date: 2026-08-06 16:17:36-0400 > From: DJ Delorie <dj@redhat.com> > > Alejandro Colomar <alx@kernel.org> writes: > > > Hmmmm, let's see. I couldn't do it in five words, but how about this > > schematic approach? > > > > The file may also contain > > .IR filters , > > which limit the tunables following it, > > The effects of a filter are terminated by > > any of the following: > > .IP \[bu] 3 > > The end of the file. > > .IP \[bu] > > The end of an included file. > > .IP \[bu] > > An > > .B include > > directive. > > .IP \[bu] > > A new (possibly empty) filter. > > I like it as-is, other than "why are there blank lines" but I don't care > about that ;-) We can compact them. ;-) The file may also contain .IR filters , which limit the tunables following it, The effects of a filter are terminated by any of the following: .PD 0 .IP \[bu] 3 The end of the file. .IP \[bu] The end of an included file. .IP \[bu] An .B include directive. .IP \[bu] A new (possibly empty) filter. .PD (I haven't tested; I've written it in the mail editor directly) > > Since a filter can be empty, we should document that. If we document > > that 'filter:pattern' is optional, it'd be [[filter:pattern]] (with the > > appropriate formatting differences: the inner '[' wouldn't be bold). > > However, that's likely to be confusing, so let's document that > > separately: > > > > A filter can also be empty: > > .BR [] . > > Such a filter has no effects. > > Done. I put it after the filter list, so the "also" made sense. Thanks! Have a lovely night! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-06 20:31 ` Alejandro Colomar @ 2026-08-06 20:42 ` DJ Delorie 2026-08-07 2:12 ` G. Branden Robinson 0 siblings, 1 reply; 41+ messages in thread From: DJ Delorie @ 2026-08-06 20:42 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man Alejandro Colomar <alx@kernel.org> writes: > (I haven't tested; I've written it in the mail editor directly) The placement of the .PD's is important ;-) I'll send a v5 with these, you can decide if you like them or not. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-06 20:42 ` DJ Delorie @ 2026-08-07 2:12 ` G. Branden Robinson 2026-08-07 3:29 ` DJ Delorie 2026-08-23 12:29 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar 0 siblings, 2 replies; 41+ messages in thread From: G. Branden Robinson @ 2026-08-07 2:12 UTC (permalink / raw) To: DJ Delorie; +Cc: Alejandro Colomar, linux-man [-- Attachment #1: Type: text/plain, Size: 3359 bytes --] At 2026-08-06T16:42:35-0400, DJ Delorie wrote: > Alejandro Colomar <alx@kernel.org> writes: > > (I haven't tested; I've written it in the mail editor directly) > > The placement of the .PD's is important ;-) > > I'll send a v5 with these, you can decide if you like them or not. Managing `PD` placement to achieve "compact lists" is indeed tedious. If you like, you guys can pilot groff 1.25.0's new `LS` and `LE` macros for man(7). I expect to release 1.25.0 in the next week and a half. Unlike the `MR` macro introduction/reform, `LS` and `LE` can be adopted early and without any negative consequence except a GNU troff(1) warning in category `mac`, which is not enabled by default, but which some people enable for linting purposes. If even that is unacceptable, you can add the following anywhere after the `TH` macro call and before your use of `LS`. .\" Avoid `mac` warnings from groff < 1.25. .as LS \" empty .as LE \" empty Use the `as` request instead of `ds`, lest you clobber groff 1.25's macro definitions. So how do `LS` and `LE` help? Here's groff's "NEWS" file: * The an (man) package offers new macros to ease the formatting of lists. Enclose paragraphing macros between `LS` and `LE` to identify them as list items. Doing so can mark them as "compact", ease management of their indentation, and supply hints to the output driver to improve their rendering (as with HTML). Lists can be nested. (Sub)sectioning macro calls, and the end of the document, close all open lists. See groff_man(7) for details, and groff_man_style(7) for an example. Thanks to Alex Colomar, Chet Ramey, Pádraig Brady, and Stephen Gildea for consultation and encouragement, and to Alex for selecting these macros' names. Because these macros format no text, documents employing them risk no damage to their content if the formatter does not support them. A man(7) document author can choose either to transition to these macros, to manage list "compactness" and item indentation with existing man(7) package facilities, or to employ both approaches. ...and here's groff_man(7). List enclosure macros ... .LS type [compactness [indentation]] (since groff 1.25) Start (or open) a list. type is one of “definition”, “enumerated”, or “itemized”. compactness is a Boolean value directing suppression of inter‐paragraph spacing between list items. indentation specifies an indentation amount for the body of each list item; it is then unnecessary to specify this argument to the list item macros. Use IP with a mark argument to represent an itemized or enumerated list item, and TP for a definition list item. Use IP without arguments to associate successive paragraphs with an existing list item; to these, inter‐ paragraph spacing applies even in compact lists. .LE (since groff 1.25) End (or close) the most recent open list. For groff 1.26, I hope to use the "type" property to select appropriate HTML elements to bracket paragraphs within list enclosures. See: https://savannah.gnu.org/bugs/?68335 https://savannah.gnu.org/bugs/?68424 Regards, Branden [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-07 2:12 ` G. Branden Robinson @ 2026-08-07 3:29 ` DJ Delorie 2026-08-07 3:49 ` G. Branden Robinson 2026-08-23 12:29 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar 1 sibling, 1 reply; 41+ messages in thread From: DJ Delorie @ 2026-08-07 3:29 UTC (permalink / raw) To: G. Branden Robinson; +Cc: alx, linux-man The problem I had with .PD placement was not the compactness of the list itself, but the inter-line spacing between the list and previous/following paragraphs. You just have to know to put the .PDs before the paragraphs that come after the space you want to affect: .P normal paragraph .P * list item .PD 0 .P * list item .P * list item .P * list item .PD .P normal paragraph My HTML background had me put the first .PD before the first list item, which bunched the list up against the previous paragraph. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-07 3:29 ` DJ Delorie @ 2026-08-07 3:49 ` G. Branden Robinson 2026-08-07 4:01 ` DJ Delorie 0 siblings, 1 reply; 41+ messages in thread From: G. Branden Robinson @ 2026-08-07 3:49 UTC (permalink / raw) To: DJ Delorie; +Cc: alx, linux-man [-- Attachment #1: Type: text/plain, Size: 2615 bytes --] At 2026-08-06T23:29:43-0400, DJ Delorie wrote: > The problem I had with .PD placement was not the compactness of the > list itself, but the inter-line spacing between the list and > previous/following paragraphs. You just have to know to put the .PDs > before the paragraphs that come after the space you want to affect: Right. But having to know that is one of those fiddly details that deters people from using man(7), no? https://lore.kernel.org/linux-man/xnse5q90jp.fsf@greed.delorie.com/ > .P > normal paragraph > .P > * list item > .PD 0 > .P > * list item > .P > * list item > .P > * list item > .PD > .P > normal paragraph > > My HTML background had me put the first .PD before the first list > item, which bunched the list up against the previous paragraph. Control of this sort of detail of formatting is, I submit, more straightforward with the new `LS`/`LE` macros forthcoming in groff 1.25. If you want a (compact) list bunched up against the preceding paragraph, don't put a `P`[1] between the paragraph text and the list. If you don't want it bunched, _do_ put a `P` there. Here's an illustration of your example above using each method. $ cat ATTIC/dj-delorie-demo-PD.man .TH foo 1 2026-08-06 "groff test suite" .SH Name foo \- frobnicate a bar .SH Description Baz qux. .P normal paragraph .P * list item 1 .PD 0 .P * list item 2 .P * list item 3 .P * list item 4 .PD .P normal paragraph $ cat ATTIC/dj-delorie-demo-LS-LE.man .TH foo 1 2026-08-06 "groff test suite" .SH Name foo \- frobnicate a bar .SH Description Baz qux. .P normal paragraph .P .LS itemized 1 2n .IP * list item 1 .IP * list item 2 .IP * list item 3 .IP * list item 4 .LE .P normal paragraph These render the same. Here, I'll prove it: $ nroff -man ATTIC/dj-delorie-demo-PD.man >| dj-PD.txt $ nroff -man ATTIC/dj-delorie-demo-LS-LE.man >| dj-LS-LE.txt $ cksum dj-* 3663585518 394 dj-LS-LE.txt 3663585518 394 dj-PD.txt Since groff 1.25.0 isn't released yet, let me add full disclosure. $ nroff --version | head -n 1 GNU nroff (groff) version 1.25.0.rc2.16-0e05a The result? $ cat dj-LS-LE.txt foo(1) General Commands Manual foo(1) Name foo - frobnicate a bar Description Baz qux. normal paragraph * list item 1 * list item 2 * list item 3 * list item 4 normal paragraph groff test suite 2026‐08‐06 foo(1) Regards, Branden [1] or its synonyms `PP` or `LP` [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-07 3:49 ` G. Branden Robinson @ 2026-08-07 4:01 ` DJ Delorie 2026-08-07 4:09 ` G. Branden Robinson 0 siblings, 1 reply; 41+ messages in thread From: DJ Delorie @ 2026-08-07 4:01 UTC (permalink / raw) To: G. Branden Robinson; +Cc: alx, linux-man "G. Branden Robinson" <g.branden.robinson@gmail.com> writes: > Right. But having to know that is one of those fiddly details that > deters people from using man(7), no? Sure. I vastly prefer semantic syntax like <ul> in HTML to the presentation syntax in roff. My complaint was just that I didn't know how .PD worked and had to figure out where to put them, because placement mattered and didn't do what I initially expected. ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config 2026-08-07 4:01 ` DJ Delorie @ 2026-08-07 4:09 ` G. Branden Robinson 0 siblings, 0 replies; 41+ messages in thread From: G. Branden Robinson @ 2026-08-07 4:09 UTC (permalink / raw) To: DJ Delorie; +Cc: alx, linux-man [-- Attachment #1: Type: text/plain, Size: 665 bytes --] At 2026-08-07T00:01:44-0400, DJ Delorie wrote: > "G. Branden Robinson" <g.branden.robinson@gmail.com> writes: > > Right. But having to know that is one of those fiddly details that > > deters people from using man(7), no? > > Sure. I vastly prefer semantic syntax like <ul> in HTML to the > presentation syntax in roff. My complaint was just that I didn't know > how .PD worked and had to figure out where to put them, because > placement mattered and didn't do what I initially expected. Yes; I believe that's a fair criticism of `PD`, and is one reason I think the new `LS`/`LE` macros can be helpful to man(7) page authors. Regards, Branden [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-07 2:12 ` G. Branden Robinson 2026-08-07 3:29 ` DJ Delorie @ 2026-08-23 12:29 ` Alejandro Colomar 2026-08-23 13:27 ` G. Branden Robinson 1 sibling, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-23 12:29 UTC (permalink / raw) To: G. Branden Robinson; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 4649 bytes --] [CC -= DJ] Hi Branden, > Date: 2026-08-06 21:12:56-0500 > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > At 2026-08-06T16:42:35-0400, DJ Delorie wrote: > > Alejandro Colomar <alx@kernel.org> writes: > > > (I haven't tested; I've written it in the mail editor directly) > > > > The placement of the .PD's is important ;-) > > > > I'll send a v5 with these, you can decide if you like them or not. > > Managing `PD` placement to achieve "compact lists" is indeed tedious. > > If you like, you guys can pilot groff 1.25.0's new `LS` and `LE` macros > for man(7). I expect to release 1.25.0 in the next week and a half. Oops, I forgot about this before pushing. I can still patch the page to do that. I was planning to release tomorrow, so it'd be interesting to have one page with that. BTW, I haven't heard of Mr. Sed for some long time. It'd be nice to meet him again. ;-) I've tried building groff from git HEAD now, and have some issues. Bootstrap succeeds, configure succeeds, and then make(1) eventually fails: $ make GEN doc/groff.html Cannot find a locale compatible with document strings translations doc/groff.texi:12253: warning: @image file `line-layout' (for HTML) not found, using `line-layout.png' doc/groff.texi:26767: warning: @image file `gnu' (for HTML) not found, using `gnu.png' cp: cannot stat './doc/gnu.png': No such file or directory cp: cannot stat './doc/line-layout.png': No such file or directory make: *** [Makefile:20047: doc/groff.html] Error 1 Do you know what's wrong? Have a lovley day! Alex > > Unlike the `MR` macro introduction/reform, `LS` and `LE` can be adopted > early and without any negative consequence except a GNU troff(1) warning > in category `mac`, which is not enabled by default, but which some > people enable for linting purposes. > > If even that is unacceptable, you can add the following anywhere after > the `TH` macro call and before your use of `LS`. > > .\" Avoid `mac` warnings from groff < 1.25. > .as LS \" empty > .as LE \" empty > > Use the `as` request instead of `ds`, lest you clobber groff 1.25's > macro definitions. > > So how do `LS` and `LE` help? Here's groff's "NEWS" file: > > * The an (man) package offers new macros to ease the formatting of > lists. Enclose paragraphing macros between `LS` and `LE` to identify > them as list items. Doing so can mark them as "compact", ease > management of their indentation, and supply hints to the output > driver to improve their rendering (as with HTML). Lists can be > nested. (Sub)sectioning macro calls, and the end of the document, > close all open lists. See groff_man(7) for details, and > groff_man_style(7) for an example. Thanks to Alex Colomar, Chet > Ramey, Pádraig Brady, and Stephen Gildea for consultation and > encouragement, and to Alex for selecting these macros' names. > > Because these macros format no text, documents employing them risk no > damage to their content if the formatter does not support them. A > man(7) document author can choose either to transition to these > macros, to manage list "compactness" and item indentation with > existing man(7) package facilities, or to employ both approaches. > > ...and here's groff_man(7). > > List enclosure macros > ... > .LS type [compactness [indentation]] > (since groff 1.25) Start (or open) a list. type is one of > “definition”, “enumerated”, or “itemized”. compactness is a > Boolean value directing suppression of inter‐paragraph > spacing between list items. indentation specifies an > indentation amount for the body of each list item; it is > then unnecessary to specify this argument to the list item > macros. Use IP with a mark argument to represent an > itemized or enumerated list item, and TP for a definition > list item. Use IP without arguments to associate successive > paragraphs with an existing list item; to these, inter‐ > paragraph spacing applies even in compact lists. > > .LE (since groff 1.25) End (or close) the most recent open list. > > For groff 1.26, I hope to use the "type" property to select appropriate > HTML elements to bracket paragraphs within list enclosures. > > See: > > https://savannah.gnu.org/bugs/?68335 > https://savannah.gnu.org/bugs/?68424 > > Regards, > Branden -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 12:29 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar @ 2026-08-23 13:27 ` G. Branden Robinson 2026-08-23 13:55 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: G. Branden Robinson @ 2026-08-23 13:27 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 3033 bytes --] Hi Alex, At 2026-08-23T14:29:54+0200, Alejandro Colomar wrote: > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > At 2026-08-06T16:42:35-0400, DJ Delorie wrote: > > > Alejandro Colomar <alx@kernel.org> writes: > > > > (I haven't tested; I've written it in the mail editor directly) > > > > > > The placement of the .PD's is important ;-) > > > > > > I'll send a v5 with these, you can decide if you like them or not. > > > > Managing `PD` placement to achieve "compact lists" is indeed tedious. > > > > If you like, you guys can pilot groff 1.25.0's new `LS` and `LE` > > macros for man(7). I expect to release 1.25.0 in the next week and > > a half. > > Oops, I forgot about this before pushing. I can still patch the page > to do that. I was planning to release tomorrow, so it'd be > interesting to have one page with that. Yes, definitely--I'm excited to see it "in the wild" outside of groff's own pages! > BTW, I haven't heard of Mr. Sed for some long time. It'd be nice to > meet him again. ;-) I'll knock on his coffin and feed him some synthetic blood to rouse him once I've released groff 1.25 final. > I've tried building groff from git HEAD now, and have some issues. > Bootstrap succeeds, configure succeeds, and then make(1) eventually > fails: > > $ make > GEN doc/groff.html > Cannot find a locale compatible with document strings translations > doc/groff.texi:12253: warning: @image file `line-layout' (for HTML) not found, using `line-layout.png' > doc/groff.texi:26767: warning: @image file `gnu' (for HTML) not found, using `gnu.png' > cp: cannot stat './doc/gnu.png': No such file or directory > cp: cannot stat './doc/line-layout.png': No such file or directory > make: *** [Makefile:20047: doc/groff.html] Error 1 > > Do you know what's wrong? More or less. It turns out to be damned hard to balance the requirements of (1) Automake maintainer mode; (2) building from Git repository checkouts; and (3) building from distribution archives. Bruno Haible has been helpful in finding scenarios that don't work. https://lists.gnu.org/archive/html/groff/2026-08/msg00039.html In the meantime, building from the most recent release candidate archive _should_ work. https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz.sig ...at any rate, it just did for me. 2026-08-23 08:22:22-0500 mkdir /tmp/rando 2026-08-23 08:22:24-0500 cd /tmp/rando 2026-08-23 08:22:28-0500 wget 'https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz' 2026-08-23 08:22:33-0500 wget 'https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz.sig' 2026-08-23 08:23:29-0500 gpg --verify groff-1.25.0.rc2.tar.gz{.sig,} 2026-08-23 08:23:36-0500 tar xf groff-1.25.0.rc2.tar.gz 2026-08-23 08:23:38-0500 cd groff-1.25.0.rc2/ 2026-08-23 08:23:55-0500 ./configure --prefix=$HOME && make -j Build finished successfully for me in about 60 seconds. Regards, Branden [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 13:27 ` G. Branden Robinson @ 2026-08-23 13:55 ` Alejandro Colomar 2026-08-23 14:16 ` G. Branden Robinson 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-23 13:55 UTC (permalink / raw) To: G. Branden Robinson; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 4853 bytes --] Hi Branden, > Date: 2026-08-23 08:27:49-0500 > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > [...] > > > I've tried building groff from git HEAD now, and have some issues. > > Bootstrap succeeds, configure succeeds, and then make(1) eventually > > fails: > > > > $ make > > GEN doc/groff.html > > Cannot find a locale compatible with document strings translations > > doc/groff.texi:12253: warning: @image file `line-layout' (for HTML) not found, using `line-layout.png' > > doc/groff.texi:26767: warning: @image file `gnu' (for HTML) not found, using `gnu.png' > > cp: cannot stat './doc/gnu.png': No such file or directory > > cp: cannot stat './doc/line-layout.png': No such file or directory > > make: *** [Makefile:20047: doc/groff.html] Error 1 > > > > Do you know what's wrong? > > More or less. It turns out to be damned hard to balance the requirements > of (1) Automake maintainer mode; (2) building from Git repository > checkouts; and (3) building from distribution archives. Bruno Haible > has been helpful in finding scenarios that don't work. > > https://lists.gnu.org/archive/html/groff/2026-08/msg00039.html Hmmmm, now it rings a bell. bootstrap said something about configure with maintainer mode, but I ignored that, since I had never used maintainer mode. After building with maintainer mode, it works a little bit better. At least I could install the binaries. I still see some errors, but I hope they're unimportant. alx@devuan:~/src/gnu/groff/master$ git log --pretty=reference -1 144585c33ae8 (roff(7): Fix content and style nits., 2026-08-09) alx@devuan:~/src/gnu/groff/master$ set -o pipefail; alx@devuan:~/src/gnu/groff/master$ ./bootstrap |& tail -n1; echo $? ./bootstrap: done. Now you can run './configure --enable-maintainer-mode'. 0 alx@devuan:~/src/gnu/groff/master$ ./configure --enable-maintainer-mode --prefix=/opt/local/gnu/groff/test/ |& tail; echo $? a --with-appdefdir option). If the gxditview app-defaults are installed in a directory that is not one of the default X11 directories for this purpose (common defaults are /usr/lib/X11/app-defaults, /usr/share/X11/app-defaults, and /etc/X11/app-defaults), you will have to set the environment variable XFILESEARCHPATH to this path. More details can be found in the X(7) manual page, or in the document "X Toolkit Intrinsics - C Language Interface manual". 0 alx@devuan:~/src/gnu/groff/master$ make |& tail -n1; echo $? make[1]: Leaving directory '/srv/alx/src/gnu/groff/master' 0 alx@devuan:~/src/gnu/groff/master$ sudo make install |& tail; echo $? install: cannot stat 'doc/img/webpage*': No such file or directory make[4]: *** [Makefile:19998: install_doc_examples] Error 1 make[4]: Leaving directory '/srv/alx/src/gnu/groff/master' make[3]: *** [Makefile:16833: install-data-am] Error 2 make[3]: Leaving directory '/srv/alx/src/gnu/groff/master' make[2]: *** [Makefile:16426: install-am] Error 2 make[2]: Leaving directory '/srv/alx/src/gnu/groff/master' make[1]: *** [Makefile:13346: install-recursive] Error 1 make[1]: Leaving directory '/srv/alx/src/gnu/groff/master' make: *** [Makefile:16419: install] Error 2 2 > In the meantime, building from the most recent release candidate archive > _should_ work. > > https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz > https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz.sig > > ...at any rate, it just did for me. > > 2026-08-23 08:22:22-0500 mkdir /tmp/rando > 2026-08-23 08:22:24-0500 cd /tmp/rando > 2026-08-23 08:22:28-0500 wget 'https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz' > 2026-08-23 08:22:33-0500 wget 'https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz.sig' > 2026-08-23 08:23:29-0500 gpg --verify groff-1.25.0.rc2.tar.gz{.sig,} > 2026-08-23 08:23:36-0500 tar xf groff-1.25.0.rc2.tar.gz > 2026-08-23 08:23:38-0500 cd groff-1.25.0.rc2/ > 2026-08-23 08:23:55-0500 ./configure --prefix=$HOME && make -j > Build finished successfully for me in about 60 seconds. Out of curiosity, where did you get those timestamps from? Does your history file store them? Using groff from git HEAD, I see the list as this: $ cat ls.man .TH a s d f .SH test foo .LS .IP \[bu] 3 bar .IP \[bu] baz .LS .P qwe $ /opt/local/gnu/groff/20260823_master/bin/groff -man -Tutf8 ./ls.man a(s) a(s) test foo • bar • baz qwe f d a(s) Is this intended? I thought it would imply PD 0. Cheers, Alex > > Regards, > Branden -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 13:55 ` Alejandro Colomar @ 2026-08-23 14:16 ` G. Branden Robinson 2026-08-23 15:06 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: G. Branden Robinson @ 2026-08-23 14:16 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man [-- Attachment #1.1: Type: text/plain, Size: 5526 bytes --] Hi Alex, At 2026-08-23T15:55:29+0200, Alejandro Colomar wrote: > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > > Do you know what's wrong? > > > > More or less. It turns out to be damned hard to balance the > > requirements of (1) Automake maintainer mode; (2) building from Git > > repository checkouts; and (3) building from distribution archives. > > Bruno Haible has been helpful in finding scenarios that don't work. > > > > https://lists.gnu.org/archive/html/groff/2026-08/msg00039.html > > Hmmmm, now it rings a bell. bootstrap said something about configure > with maintainer mode, but I ignored that, since I had never used > maintainer mode. Right. I introduced that very recently during the RCs for 1.25.0, because it seemed necessary. But as shown, Bruno has proposed patches ripping it back out. I'm pretty frustrated with Automake's lack of explicit support for building from Git working copies. Or maybe it's brilliantly documented somewhere I haven't seen yet... > After building with maintainer mode, it works a little bit better. > At least I could install the binaries. I still see some errors, but > I hope they're unimportant. > > alx@devuan:~/src/gnu/groff/master$ git log --pretty=reference -1 > 144585c33ae8 (roff(7): Fix content and style nits., 2026-08-09) > alx@devuan:~/src/gnu/groff/master$ set -o pipefail; > alx@devuan:~/src/gnu/groff/master$ ./bootstrap |& tail -n1; echo $? > ./bootstrap: done. Now you can run './configure --enable-maintainer-mode'. > 0 > alx@devuan:~/src/gnu/groff/master$ ./configure --enable-maintainer-mode --prefix=/opt/local/gnu/groff/test/ |& tail; echo $? > a --with-appdefdir option). > > If the gxditview app-defaults are installed in a directory that is not > one of the default X11 directories for this purpose (common defaults > are /usr/lib/X11/app-defaults, /usr/share/X11/app-defaults, and > /etc/X11/app-defaults), you will have to set the environment variable > XFILESEARCHPATH to this path. More details can be found in the X(7) > manual page, or in the document "X Toolkit Intrinsics - C Language > Interface manual". > > 0 That's harmless. I got the same thing. As the note implies, this is only a potential issue if you want to use gxditview from that build. gxditview changes so slowly that there's little advantage in that. Some updates to it are on my long to-do list, but not high priority because few people ever seem to use the program. > alx@devuan:~/src/gnu/groff/master$ make |& tail -n1; echo $? > make[1]: Leaving directory '/srv/alx/src/gnu/groff/master' > 0 > alx@devuan:~/src/gnu/groff/master$ sudo make install |& tail; echo $? > install: cannot stat 'doc/img/webpage*': No such file or directory > make[4]: *** [Makefile:19998: install_doc_examples] Error 1 > make[4]: Leaving directory '/srv/alx/src/gnu/groff/master' > make[3]: *** [Makefile:16833: install-data-am] Error 2 > make[3]: Leaving directory '/srv/alx/src/gnu/groff/master' > make[2]: *** [Makefile:16426: install-am] Error 2 > make[2]: Leaving directory '/srv/alx/src/gnu/groff/master' > make[1]: *** [Makefile:13346: install-recursive] Error 1 > make[1]: Leaving directory '/srv/alx/src/gnu/groff/master' > make: *** [Makefile:16419: install] Error 2 > 2 I do _not_ get such errors. Shell session attached. ...but I'm building _from the release candidate archive_, as I advised you to do. > > Build finished successfully for me in about 60 seconds. > > Out of curiosity, where did you get those timestamps from? Does your > history file store them? Yes. That's simply the output of Bash's "history" built-in. I chopped off the command numbers and removed irrelevancies like "ls". > Using groff from git HEAD, I see the list as this: > > $ cat ls.man > .TH a s d f > .SH test > foo > .LS > .IP \[bu] 3 > bar > .IP \[bu] > baz > .LS > .P > qwe > $ /opt/local/gnu/groff/20260823_master/bin/groff -man -Tutf8 ./ls.man > a(s) a(s) > > test > foo > > • bar > > • baz > > qwe > > f d a(s) > > Is this intended? I thought it would imply PD 0. Yes, it's intended. If you want the list compact, you have to say so. Also, you need to say what kind of list you're presenting. groff_man(7): .LS type [compactness [indentation]] (since groff 1.25) Start (or open) a list. type is one of “definition”, “enumerated”, or “itemized”. compactness is a Boolean value directing suppression of inter‐paragraph spacing between list items. indentation specifies an indentation amount for the body of each list item; it is then unnecessary to specify this argument to the list item macros. Use IP with a mark argument to represent an itemized or enumerated list item, and TP for a definition list item. Use IP without arguments to associate successive paragraphs with an existing list item; to these, inter‐ paragraph spacing applies even in compact lists. .LE (since groff 1.25) End (or close) the most recent open list. > .LS Say instead: .LS itemized 1 Regards, Branden [-- Attachment #1.2: groff-build-transcript.txt --] [-- Type: text/plain, Size: 85369 bytes --] ## 2026-08-23 09:05:06 bash-5.1 [8] {0} (0) branden@illithid:~/src/GIT/groff !978$ mkdir /tmp/rando ## 2026-08-23 09:05:10 bash-5.1 [8] {0} (0) branden@illithid:~/src/GIT/groff !979$ cd /tmp/rando ## 2026-08-23 09:05:11 bash-5.1 [8] {0} (0) branden@illithid:/tmp/rando !980$ wget 'https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz' --2026-08-23 09:05:13-- https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz Resolving alpha.gnu.org (alpha.gnu.org)... 2001:470:142:3::c, 209.51.188.21 Connecting to alpha.gnu.org (alpha.gnu.org)|2001:470:142:3::c|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 9400645 (9.0M) [application/x-gzip] Saving to: ‘groff-1.25.0.rc2.tar.gz’ groff-1.25.0.rc2.tar.gz 100%[=====================================================================>] 8.96M 17.5MB/s in 0.5s 2026-08-23 09:05:14 (17.5 MB/s) - ‘groff-1.25.0.rc2.tar.gz’ saved [9400645/9400645] ## 2026-08-23 09:05:14 bash-5.1 [8] {0} (0) branden@illithid:/tmp/rando !981$ wget 'https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz.sig' --2026-08-23 09:05:15-- https://alpha.gnu.org/gnu/groff/groff-1.25.0.rc2.tar.gz.sig Resolving alpha.gnu.org (alpha.gnu.org)... 2001:470:142:3::c, 209.51.188.21 Connecting to alpha.gnu.org (alpha.gnu.org)|2001:470:142:3::c|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 566 [application/pgp-signature] Saving to: ‘groff-1.25.0.rc2.tar.gz.sig’ groff-1.25.0.rc2.tar.gz.sig 100%[=====================================================================>] 566 --.-KB/s in 0s 2026-08-23 09:05:15 (6.47 MB/s) - ‘groff-1.25.0.rc2.tar.gz.sig’ saved [566/566] ## 2026-08-23 09:05:15 bash-5.1 [8] {0} (0) branden@illithid:/tmp/rando !982$ gpg --verify groff-1.25.0.rc2.tar.gz{.sig,} gpg: Signature made Sat 01 Aug 2026 08:33:36 PM CDT gpg: using RSA key 8773D61D68E30E072B10DC1AD19E9C7D71266DCE gpg: Good signature from "G. Branden Robinson <g.branden.robinson@gmail.com>" [ultimate] ## 2026-08-23 09:05:17 bash-5.1 [8] {0} (0) branden@illithid:/tmp/rando !983$ tar xf groff-1.25.0.rc2.tar.gz ## 2026-08-23 09:05:22 bash-5.1 [8] {0} (0) branden@illithid:/tmp/rando !984$ cd groff-1.25.0.rc2/ ## 2026-08-23 09:05:24 bash-5.1 [8] {0} (0) branden@illithid:/tmp/rando/groff-1.25.0.rc2 !985$ ./configure --prefix=$HOME && make -j && make install checking that groff version string has valid format... 1.25.0 valid checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to enable C11 features... none needed checking whether the compiler is clang... no checking for compiler option needed when checking for declarations... none checking how to run the C preprocessor... gcc -E checking for grep that handles long lines and -e... /home/branden/bin/grep checking for egrep... /home/branden/bin/grep -E checking for ANSI C header files... yes checking for sys/types.h... yes checking for sys/stat.h... yes checking for stdlib.h... yes checking for string.h... yes checking for memory.h... yes checking for strings.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for unistd.h... yes checking for wchar.h... yes checking for minix/config.h... no checking for stdbool.h... yes checking for uchar.h... yes checking for unistd.h... (cached) yes checking for features.h... yes checking for getopt.h... yes checking for threads.h... yes checking for limits.h... yes checking for inttypes.h... (cached) yes checking for sys/types.h... (cached) yes checking for stdint.h... (cached) yes checking for crtdefs.h... no checking for wctype.h... yes checking for xlocale.h... no checking for math.h... yes checking for sys/mman.h... yes checking for sys/param.h... yes checking for pthread.h... yes checking for sys/stat.h... (cached) yes checking for sys/time.h... yes checking for stdckdint.h... no checking for stdcountof.h... no checking for sys/socket.h... yes checking for strings.h... (cached) yes checking for sys/wait.h... yes checking for stdlib.h... (cached) yes checking whether it is safe to define __EXTENSIONS__... yes checking whether _XOPEN_SOURCE should be defined... no checking for a BSD-compatible install... /home/branden/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /home/branden/bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether make supports the include directive... yes (GNU style) checking whether make supports nested variables... yes checking dependency style of gcc... gcc3 checking whether to enable maintainer-specific portions of Makefiles... no checking whether make supports nested variables... (cached) yes checking for gcc... (cached) gcc checking whether we are using the GNU C compiler... (cached) yes checking whether gcc accepts -g... (cached) yes checking for gcc option to enable C11 features... (cached) unsupported checking for gcc option to enable C99 features... none needed checking whether the compiler is clang... (cached) no checking for compiler option needed when checking for declarations... (cached) none checking for g++... g++ checking whether we are using the GNU C++ compiler... yes checking whether g++ accepts -g... yes checking for g++ option to enable C++11 features... (cached) unsupported checking for g++ option to enable C++98 features... none needed checking dependency style of g++... gcc3 checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu checking for Minix Amsterdam compiler... no checking for ar... ar checking for ranlib... ranlib checking for gcc option to support large files... none needed checking for size_t... yes checking for working alloca.h... yes checking for alloca... yes checking whether the preprocessor supports include_next... yes checking whether source code line length is unlimited... yes checking whether char8_t is correctly defined... no checking whether char16_t is correctly defined... yes checking whether char32_t is correctly defined... yes checking whether the C++ compiler has <uchar.h>... yes checking for bit size of wchar_t... 32 checking for mbstate_t... yes checking for mbsinit... yes checking for mbrtowc... yes checking for symlink... yes checking for snprintf... yes checking for vasnprintf... no checking for iswcntrl... yes checking for lstat... yes checking for mprotect... yes checking for readlink... yes checking for vasprintf... yes checking for wcwidth... yes checking for nl_langinfo and CODESET... yes checking for a traditional japanese locale... none checking for an english Unicode locale... en_US.UTF-8 checking for a transitional chinese locale... none checking whether mbrtowc handles incomplete characters... yes checking whether mbrtowc works as well as mbtowc... guessing yes checking whether mbrtoc32 is declared... yes checking for mbrtoc32... yes checking for a traditional french locale... none checking whether mbrtoc32 works as well as mbrtowc... guessing yes checking whether c32rtomb is declared... yes checking for c32rtomb... yes checking whether c32rtomb works as well as wcrtomb... guessing yes checking for complete errno.h... yes checking whether ctype.h defines __header_inline... no checking for working fcntl.h... yes checking for pid_t... yes checking for mode_t... yes checking whether byte ordering is bigendian... no checking whether pow can be used without linking with libm... no checking whether pow can be used with libm... yes checking whether frexp() can be used without linking with libm... yes checking whether alarm is declared... yes checking whether frexp works... yes checking whether trunc is declared... yes checking whether isnan(double) can be used without linking with libm... yes checking whether ldexp() can be used without linking with libm... yes checking whether ldexp works... yes checking for stdint.h... yes checking for inttypes.h... yes checking whether printf supports size specifiers as in C99... yes checking whether printf supports size specifiers as in C23... no checking whether printf supports 'long double' arguments... yes checking whether printf supports infinite 'double' arguments... yes checking whether long double and double are the same... no checking whether printf supports infinite 'long double' arguments... yes checking whether printf supports the 'a' and 'A' directives... yes checking whether printf supports the 'b' directive... no checking whether printf supports the 'F' directive... yes checking whether printf supports the 'ls' directive... yes checking whether printf supports the 'lc' directive correctly... yes checking whether printf supports POSIX/XSI format strings with positions... yes checking whether printf supports the grouping flag... yes checking whether printf supports grouping on integers with a precision... guessing yes checking whether printf supports grouping with a multibyte separator... guessing yes checking whether printf supports the left-adjust flag correctly... yes checking whether printf supports the zero flag correctly... yes checking whether printf supports the alternative flag with a zero precision... yes checking whether printf supports large precisions... yes checking whether the compiler produces multi-arch binaries... no checking whether printf survives out-of-memory conditions... yes checking whether snprintf returns a byte count as in C99... yes checking whether snprintf truncates the result as in C99... yes checking for wint_t... yes checking whether wint_t is large enough... yes checking where to find the exponent in a 'double'... word 1 bit 20 checking for wcslen... yes checking for snprintf... (cached) yes checking for strnlen... yes checking for wcrtomb... yes checking whether _snprintf is declared... no checking for intmax_t... yes checking for getopt.h... (cached) yes checking for getopt_long_only... yes checking whether getopt is POSIX compatible... yes checking for working GNU getopt function... yes checking for working GNU getopt_long function... yes checking for glibc-compatible sys/cdefs.h... yes checking for pthread.h... (cached) yes checking for pthread_kill in -lpthread... yes checking whether POSIX threads API is available... yes checking whether setlocale (LC_ALL, NULL) is thread-safe... yes checking whether setlocale (category, NULL) is thread-safe... yes checking whether limits.h has WORD_BIT, BOOL_WIDTH etc.... no checking whether stdint.h conforms to C99... yes checking whether stdint.h works without ISO C predefines... yes checking whether stdint.h has UINTMAX_WIDTH etc.... yes checking for C/C++ restrict keyword... __restrict__ checking where to find the exponent in a 'long double'... word 2 bit 0 checking where to find the exponent in a 'float'... word 0 bit 23 checking whether iswcntrl works... yes checking for towlower... yes checking for wctype_t... yes checking for wctrans_t... yes checking for good max_align_t... yes checking whether NULL can be used in arbitrary expressions... yes checking for unreachable in C... no checking whether nullptr_t needs <stddef.h>... yes checking whether <stddef.h> is idempotent... guessing yes checking whether locale.h defines locale_t... yes checking whether locale.h defines _locale_t... no checking whether locale.h conforms to POSIX:2001... yes checking whether struct lconv is properly defined... yes checking whether lstat correctly handles trailing slash... yes checking whether malloc is ptrdiff_t safe... yes checking whether malloc, calloc set errno on failure... yes checking whether malloc (0) returns nonnull... yes checking whether NAN macro works... yes checking whether HUGE_VAL works... yes checking for inline... inline checking for MAP_ANONYMOUS... yes checking whether memchr works... yes checking whether memeq is declared... no checking whether memmem is declared... yes checking for memmem... yes checking whether memmem works... yes checking whether imported symbols can be declared weak... yes checking for multithreading API to use... posix checking for pthread_t... yes checking for pthread_spinlock_t... yes checking for pthread_spin_init... yes checking for sched.h... yes checking for struct sched_param... yes checking whether snprintf is declared... yes checking whether stat file-mode macros are broken... no checking for nlink_t... yes checking for _Bool... yes checking for stdbool.h that conforms to C99 or later... (cached) yes checking whether the C++ compiler has <stdcountof.h>... no checking whether fcloseall is declared... yes checking whether getw is declared... yes checking whether putw is declared... yes checking which flavor of printf attribute matches inttypes macros... system checking whether ecvt is declared... yes checking whether fcvt is declared... yes checking whether gcvt is declared... yes checking whether MB_CUR_MAX is correct... yes checking whether streq is declared... no checking whether strerror(0) succeeds... yes checking whether strsignal is declared... yes checking for off64_t... yes checking for blksize_t... yes checking for blkcnt_t... yes checking for struct timespec in <time.h>... yes checking for TIME_UTC in <time.h>... yes checking whether execvpe is declared... yes checking whether vsnprintf is declared... yes checking whether <wchar.h> uses 'inline' correctly... yes checking whether wcsdup is declared... yes checking for C compiler option to allow warnings... -Wno-error checking for alloca as a compiler built-in... yes checking for static_assert... yes, an <assert.h> macro checking for bool, true, false... no checking for __builtin_expect... yes checking whether fabs can be used without linking with libm... no checking whether fabs can be used with libm... yes checking whether float.h conforms to ISO C23... no checking whether conversion from 'int' to 'long double' works... yes checking for ptrdiff_t... yes checking whether free is known to preserve errno... no checking whether frexp works... (cached) yes checking whether frexpl is declared... yes checking whether frexpl() can be used without linking with libm... yes checking whether frexpl works... yes checking for __fseterr... no checking whether isfinite is declared... yes checking whether isfinite(long double) works... yes checking whether isinf is declared... yes checking whether isinf(long double) works... yes checking whether isnan(double) can be used without linking with libm... (cached) yes checking whether isnan(float) can be used without linking with libm... yes checking whether isnan(float) works... yes checking whether isnan(long double) can be used without linking with libm... yes checking whether isnanl works... yes checking for iswblank... yes checking whether iswblank is declared... yes checking whether iswdigit is ISO C compliant... yes checking whether iswpunct is consistent with ispunct... yes checking whether iswxdigit is ISO C compliant... yes checking whether ldexp works... (cached) yes checking whether localeconv works... yes checking whether mbrtoc32 works on empty input... yes checking whether the C locale is free of encoding errors... no checking whether mbrtoc32 works in an UTF-8 locale... yes checking whether mbrtowc handles a NULL pwc argument... yes checking whether mbrtowc has a correct return value... yes checking whether mbrtowc returns 0 when parsing a NUL character... guessing yes checking whether mbrtowc stores incomplete characters... no checking whether mbrtowc works on empty input... yes checking whether the C locale is free of encoding errors... no checking whether mbrtowc recognizes invalid UTF-8... yes checking whether memmem works in linear time... yes checking for memmem... (cached) yes checking whether memmem works... (cached) yes checking whether frexp works... (cached) yes checking whether ldexp can be used without linking with libm... (cached) yes checking whether frexpl() can be used without linking with libm... (cached) yes checking whether frexpl works... (cached) yes checking whether frexpl is declared... (cached) yes checking whether ldexpl() can be used without linking with libm... yes checking whether ldexpl works... yes checking whether ldexpl is declared... yes checking for PTHREAD_CREATE_DETACHED... yes checking for PTHREAD_MUTEX_RECURSIVE... yes checking for PTHREAD_MUTEX_ROBUST... yes checking for PTHREAD_PROCESS_SHARED... yes checking whether pthread_once works... yes checking whether pthread_once can be used without linking with libpthread... no checking whether readlink signature is correct... yes checking whether readlink handles trailing slash correctly... yes checking whether readlink truncates results correctly... yes checking for signbit macro... yes checking for signbit compiler built-ins... yes checking for SIZE_MAX... yes checking for snprintf... (cached) yes checking whether snprintf respects a size of 1... yes checking for ssize_t... yes checking whether stat handles trailing slashes on files... yes checking for struct stat.st_atim.tv_nsec... yes checking whether struct stat.st_atim is of type struct timespec... yes checking for struct stat.st_birthtimespec.tv_nsec... no checking for struct stat.st_birthtimensec... no checking for struct stat.st_birthtim.tv_nsec... no checking for strcasecmp... yes checking whether strcasecmp works... guessing yes checking for working strerror function... yes checking for strncasecmp... yes checking whether strcasecmp works... (cached) guessing yes checking whether strncasecmp is declared... yes checking for strsignal... yes checking whether strsignal always returns a string... yes checking whether trunc is declared... (cached) yes checking whether unlink honors trailing slashes... yes checking whether unlink of a parent directory fails as it should... guessing yes checking for variable-length arrays... yes checking for ptrdiff_t... (cached) yes checking for vsnprintf... yes checking whether snprintf respects a size of 1... (cached) yes checking whether wcwidth is declared... yes checking whether wcwidth works reasonably in UTF-8 locales... yes checking whether to install .cmd wrapper scripts for Windows... no checking for X... libraries , headers checking for gethostbyname... yes checking for connect... yes checking for remove... yes checking for shmat... yes checking for IceConnectionNumber in -lICE... yes checking for Xaw library and header files... yes checking for Xmu library and header files... yes checking for a sed that does not truncate output... /usr/bin/sed checking for perl... /usr/bin/perl checking for perl version... 5.32.1 checking for lpr... lpr checking for lp... lp checking for lpq... lpq checking option to use when spooling DVI files... -d checking for egrep... (cached) /home/branden/bin/grep -E checking for bison... bison -y checking for m4... m4 checking for makeinfo... makeinfo checking for makeinfo version... 6.7 checking for texi2dvi... texi2dvi checking for tex... found checking for ranlib... (cached) ranlib checking for install-info... install-info checking whether ln -s works... yes checking for xpmtoppm... found checking for pkg-config... /usr/bin/pkg-config checking pkg-config is at least version 0.9.0... yes checking for UCHARDET... yes checking for csh hash hack... no checking for stdbool.h... (cached) yes checking stddef.h usability... yes checking stddef.h presence... yes checking for stddef.h... yes checking for stdlib.h... (cached) yes checking for unistd.h... (cached) yes checking dirent.h usability... yes checking dirent.h presence... yes checking for dirent.h... yes checking for limits.h... (cached) yes checking sys/dir.h usability... yes checking sys/dir.h presence... yes checking for sys/dir.h... yes checking for string.h... (cached) yes checking for strings.h... (cached) yes checking for math.h... (cached) yes checking for sys/time.h... (cached) yes checking direct.h usability... no checking direct.h presence... no checking for direct.h... no checking process.h usability... no checking process.h presence... no checking for process.h... no checking whether -D_POSIX_SOURCE is necessary... no checking for return type of srand... void checking whether gettimeofday must be declared... no checking whether popen must be declared... no checking whether pclose must be declared... no checking whether rand must be declared... no checking whether srand must be declared... no checking whether vfprintf must be declared... no checking for sys_nerr in <errno.h>, <stdio.h>, or <stdlib.h>... yes checking for sys_errlist in <errno.h>, <stdio.h>, or <stdlib.h>... yes checking C++ <osfcn.h>... no checking C++ <limits.h>... yes checking C++ <inttypes.h>... yes checking for unsigned long long... yes checking for declaration of time_t... yes checking for return type of signal handlers... void checking whether byte ordering is bigendian... (cached) no checking for main in -lc... yes checking for sin in -lm... yes checking for ld used by gcc... /usr/bin/ld checking if the linker (/usr/bin/ld) is GNU ld... yes checking for shared library run path origin... done checking how to run the C++ preprocessor... g++ -E checking for iconv... yes checking for working iconv... yes checking for iconv declaration... extern size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); checking for getpagesize... yes checking for working mmap... yes checking for getcwd... yes checking for strtol... yes checking for gettimeofday... yes checking for isatty... yes checking for kill... yes checking for rename... yes checking for setlocale... yes checking for strdup... yes checking for strsep... yes checking for mkstemp... yes checking whether getc_unlocked is declared... yes checking for nl_langinfo and CODESET... (cached) yes checking whether ISO C++98 array deletion syntax is supported... yes checking whether C preprocessor uses pre-ISO C90 syntax... no checking w_coredump... no checking default value for grops -b option... 0 checking default paper format... letter (inferred from /etc/papersize) checking for existing troff installation... no checking file name prefix of system macro packages... (none) checking for system macro packages to make available... (none) checking separator character to use in groff search paths... : checking for gs... gs checking for pnmcrop... found checking for pamcut... found checking for pnmtopng... found checking for pnmtops... found checking for ps2ps... found checking for URW fonts in Type 1/PFB format... found in /usr/share/fonts/type1/urw-base35/ checking for options to make PNM tools quiet... -quiet checking whether pnmtops accepts the '-nosetpage' option... yes checking whether 'make' defines 'RM'... yes checking for a diff program that supports option -D... diff checking whether 'test' supports '-ef' option... yes checking for gs version with good left sidebearing handling... got 9.53.3 (buggy) checking whether we are using the GNU C Library >= 2.1 or uClibc... yes checking that generated files are newer than configure... done configure: creating ./config.status config.status: creating Makefile config.status: creating test-groff config.status: creating src/include/config.h config.status: executing depfiles commands config.status: executing mkdir-bison-paths commands GNU roff version 1.25.0.rc2 configuration summary ---------------------------------------------------------------------- installation directory prefix : /home/branden C++ compiler and options : g++ -g -O2 C compiler and options : gcc -g -O2 Perl interpreter version : 5.32.1 Ghostscript command : gs URW fonts directory : /usr/share/fonts/type1/urw-base35/ gropdf service level : full X11 support : enabled X11 app defaults directory : /home/branden/lib/X11/app-defaults default paper format : letter 'groff -l' uses print spooler : lpr preconv can use uchardet library : yes can build groff.{info,html,txt} : yes can build groff.{dvi,pdf} : yes ---------------------------------------------------------------------- configure: Default X11 application defaults directory assumed. The application defaults files for gxditview (GXditview and GXditview-color) will be installed in the following directory. /home/branden/lib/X11/app-defaults To install elsewhere, say, '/etc/X11/app-defaults', add '--with-appdefdir=/etc/X11/app-defaults' to the configure script command-line options and rerun it (the 'prefix' value has no effect on a --with-appdefdir option). If the gxditview app-defaults are installed in a directory that is not one of the default X11 directories for this purpose (common defaults are /usr/lib/X11/app-defaults, /usr/share/X11/app-defaults, and /etc/X11/app-defaults), you will have to set the environment variable XFILESEARCHPATH to this path. More details can be found in the X(7) manual page, or in the document "X Toolkit Intrinsics - C Language Interface manual". configure: Buggy version of Ghostscript detected. Ghostscript versions 9.00 <= x < 9.54 suffer from a rendering glitch that affects the AT&T troff (and groff) special character '\(lh'; see <https://bugs.ghostscript.com/show_bug.cgi?id=703187>. If your version of Ghostscript has not been patched to fix this problem, you may need to work around it in groff documents you render for the PostScript (and, for tbl(1) tables, HTML) output devices. GEN lib/alloca.h GEN lib/fcntl.h GEN lib/float.h GEN lib/inttypes.h GEN lib/limits.h GEN lib/locale.h GEN lib/math.h GEN lib/pthread.h GEN lib/sched.h GEN lib/stdckdint.h GEN lib/stdcountof.h GEN lib/stddef.h GEN lib/stdio.h GEN lib/stdlib.h GEN lib/string.h GEN lib/strings.h GEN lib/sys/stat.h GEN lib/sys/types.h GEN lib/sys/wait.h GEN lib/time.h GEN lib/uchar.h GEN lib/unicase.h GEN lib/unictype.h GEN lib/uninorm.h GEN lib/unistd.h GEN lib/unitypes.h GEN lib/uniwidth.h GEN lib/wchar.h GEN lib/wctype.h make all-recursive make[1]: Entering directory '/tmp/rando/groff-1.25.0.rc2' make[2]: Entering directory '/tmp/rando/groff-1.25.0.rc2' GEN .version CC lib/libgnu_a-unistd.o CC lib/libgnu_a-vfzprintf.o CC lib/libgnu_a-vsnzprintf.o CC lib/libgnu_a-wctype-h.o CC lib/libgnu_a-xsize.o CC lib/libgnu_a-asnprintf.o CC lib/libgnu_a-fprintf.o CC lib/libgnu_a-printf-args.o CC lib/libgnu_a-printf-parse.o CC lib/libgnu_a-vasnprintf.o GEN src/devices/xditview/GXditview-ad.h GEN src/devices/xditview/groff_version.h GEN eqn2graph GEN gdiffmk GEN shdeps.sed GEN grap2graph GEN mmroff GEN pic2graph GEN afmtodit GEN grog GEN pdfmom GEN src/roff/troff/majorminor.cpp GEN chem GEN nroff GEN neqn GEN font/devascii/R GEN font/devascii/I GEN font/devascii/B GEN font/devascii/BI GEN font/devascii/DESC GEN font/devdvi/DESC GEN font/devhtml/R GEN font/devhtml/I GEN font/devhtml/B GEN font/devhtml/BI GEN font/devhtml/CR GEN font/devhtml/CI GEN font/devhtml/CBI GEN font/devhtml/S GEN font/devhtml/CB GEN font/devhtml/DESC GEN font/devlatin1/R GEN font/devlatin1/I GEN font/devlatin1/B GEN font/devlatin1/BI GEN font/devlatin1/DESC GEN font/devlbp/DESC GEN font/devpdf/DESC GEN font/devpdf/util/BuildFoundries GEN font/devpdf/Foundry GEN font/devpdf/symbolsl.afm GEN font/devpdf/symbolsl.pfb GEN font/devutf8/R GEN font/devutf8/I GEN font/devpdf/SS GEN font/devutf8/B GEN font/devutf8/BI GEN font/devutf8/DESC GEN font/devps/DESC GEN font/devps/prologue GEN font/devps/freeeuro.pfa GEN font/devps/zapfdr.pfa GEN font/devps/symbolsl.pfa GEN tmac/www.tmac GEN font/devlj4/DESC GEN doc/groff-man-pages-cover.groff GEN doc/ms.ms GEN contrib/hdtbl/examples/fonts_n.roff GEN contrib/hdtbl/examples/fonts_x.roff GEN doc/meref.me GEN doc/meintro.me GEN doc/meintro_fr.me CXX src/devices/grodvi/dvi.o CXX src/libs/libdriver/input.o CXX src/libs/libdriver/printer.o CXX src/libs/libgroff/libgroff_a-change_lf.o CXX src/libs/libgroff/libgroff_a-cmap.o CXX src/libs/libgroff/libgroff_a-cset.o CXX src/libs/libgroff/libgroff_a-color.o CXX src/libs/libgroff/libgroff_a-device.o CXX src/libs/libgroff/libgroff_a-curtime.o CXX src/libs/libgroff/libgroff_a-errarg.o CXX src/libs/libgroff/libgroff_a-error.o CXX src/libs/libgroff/libgroff_a-fatal.o CXX src/libs/libgroff/libgroff_a-filename.o CXX src/libs/libgroff/libgroff_a-font.o GEN contrib/sboxes/msboxes.ms CXX src/libs/libgroff/libgroff_a-fontfile.o CXX src/libs/libgroff/libgroff_a-geometry.o CXX src/libs/libgroff/libgroff_a-glyphuni.o CXX src/libs/libgroff/libgroff_a-htmlhint.o CC src/libs/libgroff/libgroff_a-iftoa.o CXX src/libs/libgroff/libgroff_a-invalid.o CC src/libs/libgroff/libgroff_a-itoa.o CXX src/libs/libgroff/libgroff_a-json_encode.o CXX src/libs/libgroff/libgroff_a-lf.o CXX src/libs/libgroff/libgroff_a-lineno.o CXX src/libs/libgroff/libgroff_a-macropath.o CXX src/libs/libgroff/libgroff_a-maxfilename.o CXX src/libs/libgroff/libgroff_a-maxpathname.o CXX src/libs/libgroff/libgroff_a-mksdir.o CXX src/libs/libgroff/libgroff_a-nametoindex.o CXX src/libs/libgroff/libgroff_a-paper.o CXX src/libs/libgroff/libgroff_a-prime.o CC src/libs/libgroff/libgroff_a-progname.o CXX src/libs/libgroff/libgroff_a-ptable.o CC src/libs/libgroff/libgroff_a-quotearg.o CXX src/libs/libgroff/libgroff_a-relocate.o CXX src/libs/libgroff/libgroff_a-searchpath.o CC src/libs/libgroff/libgroff_a-spawnvp.o CXX src/libs/libgroff/libgroff_a-string.o CXX src/libs/libgroff/libgroff_a-strsave.o CXX src/libs/libgroff/libgroff_a-symbol.o CXX src/libs/libgroff/libgroff_a-tmpfile.o CXX src/libs/libgroff/libgroff_a-tmpname.o CXX src/libs/libgroff/libgroff_a-unicode.o CXX src/libs/libgroff/libgroff_a-uniglyph.o CXX src/libs/libgroff/libgroff_a-uniuni.o CC lib/libgnu_a-c32isalnum.o CC lib/libgnu_a-c32isalpha.o CC lib/libgnu_a-c32isblank.o CC lib/libgnu_a-c32iscntrl.o CC lib/libgnu_a-c32isdigit.o CC lib/libgnu_a-c32isgraph.o CC lib/libgnu_a-c32islower.o GEN src/libs/libgroff/version.cpp CC lib/libgnu_a-c32isprint.o CC lib/libgnu_a-c32ispunct.o CC lib/libgnu_a-c32isspace.o CC lib/libgnu_a-c32isupper.o CC lib/libgnu_a-c32isxdigit.o CC lib/libgnu_a-c32tolower.o CC lib/libgnu_a-c32width.o CC lib/libgnu_a-float.o CC lib/libgnu_a-free.o CC lib/libgnu_a-fseterr.o CC lib/libgnu_a-hard-locale.o CC lib/libgnu_a-issymlink.o CC lib/libgnu_a-localcharset.o CC lib/libgnu_a-malloca.o CC lib/libgnu_a-math.o CC lib/libgnu_a-mbchar.o CC lib/libgnu_a-mbiter-aux.o CC lib/libgnu_a-mbiterf.o CC lib/libgnu_a-mbrtowc.o CC lib/libgnu_a-mbrtoc32.o CC lib/libgnu_a-mbsnlen.o CC lib/libgnu_a-mbszero.o CC lib/libgnu_a-memeq.o CC lib/glthread/libgnu_a-once.o CC lib/libgnu_a-printf-frexp.o CC lib/libgnu_a-printf-frexpl.o CC lib/libgnu_a-setlocale_null.o CC lib/libgnu_a-setlocale_null-unlocked.o CC lib/libgnu_a-stat-time.o CC lib/libgnu_a-stdlib.o CC lib/libgnu_a-streq.o CC lib/glthread/libgnu_a-threadlib.o CC lib/glthread/libgnu_a-tls.o CC lib/unicase/libgnu_a-tolower.o CC lib/unictype/libgnu_a-ctype_alnum.o CC lib/unictype/libgnu_a-ctype_alpha.o CC lib/unictype/libgnu_a-ctype_blank.o CC lib/unictype/libgnu_a-ctype_cntrl.o CC lib/unictype/libgnu_a-ctype_digit.o CC lib/unictype/libgnu_a-ctype_graph.o CC lib/unictype/libgnu_a-ctype_lower.o CC lib/unictype/libgnu_a-ctype_print.o CC lib/unictype/libgnu_a-ctype_punct.o CC lib/unictype/libgnu_a-ctype_space.o CC lib/unictype/libgnu_a-ctype_upper.o CC lib/uniwidth/libgnu_a-width.o CC lib/unictype/libgnu_a-ctype_xdigit.o CXX src/devices/grohtml/post-html.o CXX src/devices/grohtml/html-table.o CXX src/devices/grohtml/output.o CXX src/devices/grohtml/html-text.o CXX src/devices/grolbp/lbp.o CXX src/devices/grops/ps.o CXX src/devices/grolj4/lj4.o CXX src/devices/grops/psrm.o CXX src/devices/grotty/tty.o CC src/devices/xditview/gxditview-device.o CC src/devices/xditview/gxditview-draw.o CC src/devices/xditview/gxditview-Dvi.o CC src/devices/xditview/gxditview-font.o CC src/devices/xditview/gxditview-lex.o CC src/devices/xditview/gxditview-page.o CC src/devices/xditview/gxditview-parse.o CC src/devices/xditview/gxditview-xditview.o CC src/libs/libxutil/libxutil_a-DviChar.o CC src/libs/libxutil/libxutil_a-XFontName.o CC src/libs/libxutil/libxutil_a-xmalloc.o CXX src/preproc/html/pre-html.o CXX src/preproc/html/pushback.o CXX src/preproc/preconv/preconv-preconv.o CXX src/roff/groff/groff.o CC src/roff/groff/pipeline.o CXX src/utils/addftinfo/addftinfo.o CXX src/utils/addftinfo/guess.o CXX src/utils/hpftodit/hpftodit.o CXX src/utils/hpftodit/hpuni.o CXX src/utils/lkbib/lkbib.o CXX src/libs/libbib/common.o CXX src/libs/libbib/index.o CXX src/libs/libbib/linear.o CXX src/libs/libbib/search.o CC src/libs/libbib/map.o CC src/utils/pfbtops/pfbtops.o CXX src/utils/tfmtodit/tfmtodit.o CC src/utils/xtotroff/xtotroff-xtotroff.o CXX src/preproc/eqn/eqn-main.o CXX src/preproc/eqn/eqn-lex.o CXX src/preproc/eqn/eqn-box.o CXX src/preproc/eqn/eqn-limit.o CXX src/preproc/eqn/eqn-list.o CXX src/preproc/eqn/eqn-over.o CXX src/preproc/eqn/eqn-text.o CXX src/preproc/eqn/eqn-script.o CXX src/preproc/eqn/eqn-mark.o CXX src/preproc/eqn/eqn-other.o CXX src/preproc/eqn/eqn-delim.o CXX src/preproc/eqn/eqn-sqrt.o CXX src/preproc/eqn/eqn-pile.o CXX src/preproc/eqn/eqn-special.o CXX src/preproc/eqn/eqn-eqn.o CXX src/preproc/grn/hdb.o CXX src/preproc/grn/hpoint.o CXX src/preproc/grn/hgraph.o CXX src/preproc/grn/main.o CXX src/preproc/pic/pic-pic.o CXX src/preproc/pic/pic-lex.o CXX src/preproc/pic/pic-main.o CXX src/preproc/pic/pic-object.o CXX src/preproc/pic/pic-common.o CXX src/preproc/pic/pic-troff.o CXX src/preproc/pic/pic-tex.o CXX src/preproc/refer/refer-command.o CXX src/preproc/refer/refer-ref.o CXX src/preproc/refer/refer-refer.o CXX src/preproc/refer/refer-token.o CXX src/preproc/refer/refer-label.o CXX src/preproc/soelim/soelim.o CXX src/preproc/tbl/main.o CXX src/preproc/tbl/table.o CXX src/roff/troff/dictionary.o CXX src/roff/troff/div.o CXX src/roff/troff/env.o CXX src/roff/troff/input.o CXX src/roff/troff/mtsm.o CXX src/roff/troff/node.o CXX src/roff/troff/number.o CXX src/roff/troff/reg.o CXX src/roff/troff/majorminor.o CXX src/utils/indxbib/indxbib.o CC src/utils/indxbib/signal.o CXX src/utils/lookbib/lookbib.o GEN glilypond GEN gperl GEN gpinyin GEN gropdf GEN tmac/groff_man.7.man GEN tmac/groff_man_style.7.man GEN font/devpdf/download AR libdriver.a CXX src/libs/libgroff/libgroff_a-version.o AR lib/libgnu.a BuildFoundries: notice: copied grops font description AB for gropdf BuildFoundries: notice: copied grops font description ABI for gropdf BuildFoundries: notice: copied grops font description AI for gropdf BuildFoundries: notice: copied grops font description AR for gropdf BuildFoundries: notice: copied grops font description BMB for gropdf BuildFoundries: notice: copied grops font description BMBI for gropdf BuildFoundries: notice: copied grops font description BMI for gropdf BuildFoundries: notice: copied grops font description BMR for gropdf BuildFoundries: notice: copied grops font description CB for gropdf BuildFoundries: notice: copied grops font description CBI for gropdf BuildFoundries: notice: copied grops font description CI for gropdf BuildFoundries: notice: copied grops font description CR for gropdf BuildFoundries: notice: copied grops font description HB for gropdf BuildFoundries: notice: copied grops font description HBI for gropdf BuildFoundries: notice: copied grops font description HI for gropdf BuildFoundries: notice: copied grops font description HNB for gropdf BuildFoundries: notice: copied grops font description HNBI for gropdf BuildFoundries: notice: copied grops font description HNI for gropdf BuildFoundries: notice: copied grops font description HNR for gropdf BuildFoundries: notice: copied grops font description HR for gropdf BuildFoundries: notice: copied grops font description NB for gropdf BuildFoundries: notice: copied grops font description NBI for gropdf BuildFoundries: notice: copied grops font description NI for gropdf BuildFoundries: notice: copied grops font description NR for gropdf BuildFoundries: notice: copied grops font description PB for gropdf BuildFoundries: notice: copied grops font description PBI for gropdf BuildFoundries: notice: copied grops font description PI for gropdf BuildFoundries: notice: copied grops font description PR for gropdf BuildFoundries: notice: copied grops font description S for gropdf BuildFoundries: notice: copied grops font description TB for gropdf BuildFoundries: notice: copied grops font description TBI for gropdf BuildFoundries: notice: copied grops font description TI for gropdf BuildFoundries: notice: copied grops font description TR for gropdf BuildFoundries: notice: copied grops font description ZCMI for gropdf BuildFoundries: notice: copied grops font description ZD for gropdf BuildFoundries: notice: copied grops font description EURO for gropdf AR libgroff.a CXXLD grodvi CXXLD addftinfo CCLD pfbtops AR libxutil.a CCLD xtotroff CCLD gxditview BuildFoundries: notice: generated font description U-AB for gropdf CXXLD soelim CXXLD grolj4 BuildFoundries: notice: generated font description U-ABI for gropdf GEN contrib/chem/chem.1 GEN contrib/eqn2graph/eqn2graph.1 GEN contrib/gdiffmk/gdiffmk.1 GEN contrib/glilypond/glilypond.1 GEN contrib/gperl/gperl.1 GEN contrib/gpinyin/gpinyin.1 GEN contrib/grap2graph/grap2graph.1 GEN contrib/mm/mmroff.1 GEN contrib/pic2graph/pic2graph.1 GEN src/devices/grodvi/grodvi.1 GEN src/devices/grohtml/grohtml.1 GEN src/devices/grolbp/grolbp.1 GEN src/devices/grolj4/grolj4.1 GEN src/devices/gropdf/gropdf.1 GEN src/devices/grops/grops.1 GEN src/devices/grotty/grotty.1 GEN src/devices/xditview/gxditview.1 GEN src/preproc/preconv/preconv.1 BuildFoundries: notice: generated font description U-AI for gropdf GEN src/utils/addftinfo/addftinfo.1 GEN src/roff/groff/groff.1 GEN src/utils/afmtodit/afmtodit.1 GEN src/utils/grog/grog.1 GEN src/utils/hpftodit/hpftodit.1 GEN src/utils/lkbib/lkbib.1 GEN src/utils/pdfmom/pdfmom.1 GEN src/utils/pfbtops/pfbtops.1 GEN src/utils/tfmtodit/tfmtodit.1 GEN src/utils/xtotroff/xtotroff.1 GEN src/preproc/eqn/eqn.1 GEN src/preproc/eqn/neqn.1 GEN src/preproc/grn/grn.1 GEN src/preproc/pic/pic.1 GEN src/preproc/refer/refer.1 GEN src/preproc/soelim/soelim.1 GEN src/preproc/tbl/tbl.1 GEN src/roff/nroff/nroff.1 GEN src/roff/troff/troff.1 GEN src/utils/indxbib/indxbib.1 GEN src/utils/lookbib/lookbib.1 GEN man/groff_font.5 GEN man/groff_out.5 GEN man/groff_tmac.5 GEN contrib/hdtbl/groff_hdtbl.7 GEN contrib/mm/groff_mm.7 GEN contrib/mm/groff_mmse.7 GEN contrib/mom/groff_mom.7 GEN contrib/rfc1345/groff_rfc1345.7 GEN man/groff_char.7 GEN man/groff_diff.7 GEN man/groff.7 GEN man/roff.7 GEN tmac/groff_ms.7 GEN tmac/groff_man.7 GEN tmac/groff_man_style.7 GEN tmac/groff_me.7 GEN tmac/groff_mdoc.7 GEN tmac/groff_trace.7 BuildFoundries: notice: generated font description U-AR for gropdf GEN tmac/groff_www.7 CXXLD grotty CXXLD pre-grohtml CXXLD preconv CXXLD groff AR libbib.a CXXLD grn CXXLD lkbib CXXLD lookbib CXXLD tfmtodit CXXLD indxbib BuildFoundries: notice: generated font description U-BMB for gropdf CXXLD eqn BuildFoundries: notice: generated font description U-BMBI for gropdf CXXLD hpftodit CXXLD grops CXXLD refer BuildFoundries: notice: generated font description U-BMI for gropdf CXXLD grolbp BuildFoundries: notice: generated font description U-BMR for gropdf BuildFoundries: notice: generated font description U-CB for gropdf BuildFoundries: notice: generated font description U-CBI for gropdf BuildFoundries: notice: generated font description U-CI for gropdf BuildFoundries: notice: generated font description U-CR for gropdf BuildFoundries: notice: generated font description U-HB for gropdf BuildFoundries: notice: generated font description U-HBI for gropdf BuildFoundries: notice: generated font description U-HI for gropdf CXXLD pic BuildFoundries: notice: generated font description U-HNB for gropdf BuildFoundries: notice: generated font description U-HNBI for gropdf BuildFoundries: notice: generated font description U-HNI for gropdf BuildFoundries: notice: generated font description U-HNR for gropdf BuildFoundries: notice: generated font description U-HR for gropdf BuildFoundries: notice: generated font description U-NB for gropdf BuildFoundries: notice: generated font description U-NBI for gropdf BuildFoundries: notice: generated font description U-NI for gropdf BuildFoundries: notice: generated font description U-NR for gropdf CXXLD tbl BuildFoundries: notice: generated font description U-PB for gropdf BuildFoundries: notice: generated font description U-PBI for gropdf BuildFoundries: notice: generated font description U-PI for gropdf CXXLD post-grohtml BuildFoundries: notice: generated font description U-PR for gropdf BuildFoundries: notice: generated font description U-S for gropdf BuildFoundries: notice: generated font description U-TB for gropdf BuildFoundries: notice: generated font description U-TBI for gropdf BuildFoundries: notice: generated font description U-TI for gropdf BuildFoundries: notice: generated font description U-TR for gropdf BuildFoundries: notice: generated font description U-ZCMI for gropdf BuildFoundries: notice: generated font description U-ZD for gropdf CXXLD troff GROFF doc/pic.html GROFF doc/webpage.html GROFF doc/webpage.ps GROFF doc/grnexmpl.ps GROFF doc/automake.pdf GROFF doc/groff-man-pages.pdf GROFF doc/ms.pdf GROFF doc/pic.pdf GROFF doc/groff-pdf-features.pdf GROFF contrib/hdtbl/examples/color_boxes.ps GROFF contrib/hdtbl/examples/chess_board.ps GROFF contrib/hdtbl/examples/color_nested_tables.ps GROFF contrib/hdtbl/examples/color_table_cells.ps GROFF contrib/hdtbl/examples/color_transitions.ps GROFF contrib/hdtbl/examples/col_rowspan_colors.ps GROFF contrib/hdtbl/examples/fonts_n.ps GROFF contrib/hdtbl/examples/fonts_x.ps GROFF contrib/hdtbl/examples/mixed_pickles.ps GROFF contrib/hdtbl/examples/rainbow.ps GROFF contrib/hdtbl/examples/short_reference.ps GROFF contrib/mom/examples/letter.pdf GROFF contrib/mom/examples/mom-pdf.pdf GROFF contrib/mom/examples/mon_premier_doc.pdf GROFF contrib/mom/examples/sample_docs.pdf GROFF contrib/mom/examples/slide-demo.pdf GROFF contrib/mom/examples/copyright-default.pdf GROFF contrib/mom/examples/copyright-chapter.pdf GROFF contrib/mom/examples/typesetting.pdf GROFF doc/meref.ps GROFF doc/meintro.ps GROFF doc/meintro_fr.ps GROFF doc/groff-man-pages.utf8.txt GROFF contrib/sboxes/msboxes.pdf fonts_x.roff: listing fonts in ./font/devps fonts_n.roff: listing fonts in ./font/devps fonts_x.roff: listing glyphs in font 'AB' with hdtbl... fonts_n.roff: listing glyphs in font 'AB' with hdtbl... fonts_x.roff: listing glyphs in font 'ABI' with hdtbl... fonts_n.roff: listing glyphs in font 'ABI' with hdtbl... fonts_x.roff: listing glyphs in font 'AI' with hdtbl... fonts_n.roff: listing glyphs in font 'AI' with hdtbl... fonts_x.roff: listing glyphs in font 'AR' with hdtbl... fonts_n.roff: listing glyphs in font 'AR' with hdtbl... fonts_x.roff: listing glyphs in font 'BMB' with hdtbl... fonts_n.roff: listing glyphs in font 'BMB' with hdtbl... fonts_x.roff: listing glyphs in font 'BMBI' with hdtbl... fonts_n.roff: listing glyphs in font 'BMBI' with hdtbl... fonts_x.roff: listing glyphs in font 'BMI' with hdtbl... fonts_n.roff: listing glyphs in font 'BMI' with hdtbl... fonts_x.roff: listing glyphs in font 'BMR' with hdtbl... fonts_n.roff: listing glyphs in font 'BMR' with hdtbl... fonts_x.roff: listing glyphs in font 'CB' with hdtbl... fonts_n.roff: listing glyphs in font 'CB' with hdtbl... fonts_x.roff: listing glyphs in font 'CBI' with hdtbl... fonts_n.roff: listing glyphs in font 'CBI' with hdtbl... fonts_x.roff: listing glyphs in font 'CI' with hdtbl... fonts_n.roff: listing glyphs in font 'CI' with hdtbl... fonts_x.roff: listing glyphs in font 'CR' with hdtbl... fonts_n.roff: listing glyphs in font 'CR' with hdtbl... fonts_x.roff: listing glyphs in font 'CSH' with hdtbl... fonts_n.roff: listing glyphs in font 'CSH' with hdtbl... fonts_x.roff: listing glyphs in font 'CSS' with hdtbl... fonts_x.roff: listing glyphs in font 'CTH' with hdtbl... fonts_n.roff: listing glyphs in font 'CSS' with hdtbl... fonts_x.roff: listing glyphs in font 'CTS' with hdtbl... fonts_n.roff: listing glyphs in font 'CTH' with hdtbl... fonts_x.roff: listing glyphs in font 'EURO' with hdtbl... fonts_n.roff: listing glyphs in font 'CTS' with hdtbl... fonts_x.roff: listing glyphs in font 'HB' with hdtbl... fonts_n.roff: listing glyphs in font 'EURO' with hdtbl... fonts_n.roff: listing glyphs in font 'HB' with hdtbl... fonts_x.roff: listing glyphs in font 'HBI' with hdtbl... fonts_x.roff: listing glyphs in font 'HI' with hdtbl... fonts_n.roff: listing glyphs in font 'HBI' with hdtbl... fonts_x.roff: listing glyphs in font 'HNB' with hdtbl... fonts_n.roff: listing glyphs in font 'HI' with hdtbl... fonts_x.roff: listing glyphs in font 'HNBI' with hdtbl... fonts_n.roff: listing glyphs in font 'HNB' with hdtbl... fonts_x.roff: listing glyphs in font 'HNI' with hdtbl... fonts_n.roff: listing glyphs in font 'HNBI' with hdtbl... fonts_x.roff: listing glyphs in font 'HNR' with hdtbl... fonts_n.roff: listing glyphs in font 'HNI' with hdtbl... fonts_x.roff: listing glyphs in font 'HR' with hdtbl... fonts_n.roff: listing glyphs in font 'HNR' with hdtbl... fonts_x.roff: listing glyphs in font 'JPG' with hdtbl... fonts_n.roff: listing glyphs in font 'HR' with hdtbl... fonts_x.roff: listing glyphs in font 'JPM' with hdtbl... fonts_n.roff: listing glyphs in font 'JPG' with hdtbl... fonts_x.roff: listing glyphs in font 'KOG' with hdtbl... fonts_n.roff: listing glyphs in font 'JPM' with hdtbl... fonts_x.roff: listing glyphs in font 'KOM' with hdtbl... fonts_n.roff: listing glyphs in font 'KOG' with hdtbl... fonts_x.roff: listing glyphs in font 'NB' with hdtbl... fonts_n.roff: listing glyphs in font 'KOM' with hdtbl... fonts_x.roff: listing glyphs in font 'NBI' with hdtbl... fonts_n.roff: listing glyphs in font 'NB' with hdtbl... fonts_x.roff: listing glyphs in font 'NI' with hdtbl... fonts_n.roff: listing glyphs in font 'NBI' with hdtbl... fonts_x.roff: listing glyphs in font 'NR' with hdtbl... fonts_x.roff: listing glyphs in font 'PB' with hdtbl... fonts_n.roff: listing glyphs in font 'NI' with hdtbl... fonts_x.roff: listing glyphs in font 'PBI' with hdtbl... fonts_n.roff: listing glyphs in font 'NR' with hdtbl... fonts_x.roff: listing glyphs in font 'PI' with hdtbl... fonts_n.roff: listing glyphs in font 'PB' with hdtbl... fonts_x.roff: listing glyphs in font 'PR' with hdtbl... fonts_n.roff: listing glyphs in font 'PBI' with hdtbl... fonts_x.roff: listing glyphs in font 'S' with hdtbl... fonts_n.roff: listing glyphs in font 'PI' with hdtbl... fonts_x.roff: listing glyphs in font 'SS' with hdtbl... fonts_n.roff: listing glyphs in font 'PR' with hdtbl... fonts_x.roff: listing glyphs in font 'TB' with hdtbl... fonts_n.roff: listing glyphs in font 'S' with hdtbl... fonts_x.roff: listing glyphs in font 'TBI' with hdtbl... fonts_n.roff: listing glyphs in font 'SS' with hdtbl... fonts_x.roff: listing glyphs in font 'TI' with hdtbl... fonts_n.roff: listing glyphs in font 'TB' with hdtbl... fonts_x.roff: listing glyphs in font 'TR' with hdtbl... fonts_n.roff: listing glyphs in font 'TBI' with hdtbl... fonts_x.roff: listing glyphs in font 'ZCMI' with hdtbl... fonts_n.roff: listing glyphs in font 'TI' with hdtbl... fonts_x.roff: listing glyphs in font 'ZD' with hdtbl... fonts_n.roff: listing glyphs in font 'TR' with hdtbl... fonts_x.roff: listing glyphs in font 'ZDR' with hdtbl... fonts_n.roff: listing glyphs in font 'ZCMI' with hdtbl... fonts_n.roff: listing glyphs in font 'ZD' with hdtbl... fonts_n.roff: listing glyphs in font 'ZDR' with hdtbl... troff: backtrace: file '<standard input>':1075 troff:<standard input>:1075: warning: special character '.j' not defined [-w char] troff: backtrace: file '<standard input>':1481 troff:<standard input>:1481: warning: special character 'vA' not defined [-w char] troff: backtrace: file '<standard input>':1611 troff:<standard input>:1611: warning: special character 'bs' not defined [-w char] troff: backtrace: file '<standard input>':1784 troff:<standard input>:1784: warning: special character '-+' not defined [-w char] troff: backtrace: file '<standard input>':1833 troff:<standard input>:1833: warning: special character 'coproduct' not defined [-w char] troff: backtrace: file '<standard input>':1933 troff:<standard input>:1933: warning: special character '+e' not defined [-w char] make[2]: Leaving directory '/tmp/rando/groff-1.25.0.rc2' make[1]: Leaving directory '/tmp/rando/groff-1.25.0.rc2' make install-recursive make[1]: Entering directory '/tmp/rando/groff-1.25.0.rc2' make[2]: Entering directory '/tmp/rando/groff-1.25.0.rc2' make[3]: Entering directory '/tmp/rando/groff-1.25.0.rc2' /home/branden/bin/mkdir -p '/home/branden/bin' /home/branden/bin/install -c grodvi post-grohtml grolbp grolj4 grops grotty gxditview pre-grohtml preconv groff addftinfo hpftodit lkbib pfbtops tfmtodit xtotroff '/home/branden/bin' /home/branden/bin/mkdir -p '/home/branden/bin' /home/branden/bin/install -c eqn2graph gdiffmk glilypond gperl gpinyin grap2graph mmroff pic2graph gropdf afmtodit grog pdfmom '/home/branden/bin' /home/branden/bin/mkdir -p '/home/branden/bin' /home/branden/bin/install -c eqn grn pic refer soelim tbl troff indxbib lookbib '/home/branden/bin' /home/branden/bin/mkdir -p '/home/branden/bin' /home/branden/bin/install -c chem neqn nroff '/home/branden/bin' make install-exec-hook make[4]: Entering directory '/tmp/rando/groff-1.25.0.rc2' make[4]: Nothing to be done for 'install-exec-hook'. make[4]: Leaving directory '/tmp/rando/groff-1.25.0.rc2' test -d /home/branden/share/doc/groff-1.25.0/examples/chem/cstr-122 \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/doc/groff-1.25.0/examples/chem/cstr-122; for i in ./contrib/chem/examples/cstr-122/*; do \ n=`echo $i | sed 's|./contrib/chem/examples/cstr-122/||g'`; \ /home/branden/bin/install -c -m 644 $i /home/branden/share/doc/groff-1.25.0/examples/chem/cstr-122/$n; \ done test -d /home/branden/share/groff/1.25.0/tmac || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/groff/1.25.0/tmac test -d /home/branden/share/groff/1.25.0/tmac/mm || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/groff/1.25.0/tmac/mm rm -f /home/branden/share/groff/1.25.0/tmac/tmac.`if test no = yes; then for i in ""; do case "$i" in m) echo g;; esac; done; fi`m rm -f /home/branden/share/groff/1.25.0/tmac/`if test no = yes; then for i in ""; do case "$i" in m) echo g;; esac; done; fi`m.tmac /home/branden/bin/install -c -m 644 ./contrib/mm/m.tmac \ /home/branden/share/groff/1.25.0/tmac/`if test no = yes; then for i in ""; do case "$i" in m) echo g;; esac; done; fi`m.tmac LANG=C LC_ALL=C sed -e "s;^.mso m.tmac;.mso `if test no = yes; then for i in ""; do case "$i" in m) echo g;; esac; done; fi`m.tmac;g" \ ./contrib/mm/mse.tmac > /home/branden/share/groff/1.25.0/tmac/`if test no = yes; then for i in ""; do case "$i" in m) echo g;; esac; done; fi`mse.tmac test -d /home/branden/share/doc/groff-1.25.0 \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/doc/groff-1.25.0 for d in doc /tmp/rando/groff-1.25.0.rc2/doc; do \ if [ -f "$d"/groff.txt ]; then \ cp "$d"/groff.txt /home/branden/share/doc/groff-1.25.0; \ break; \ fi; \ done test -d /home/branden/share/info \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/info rm -f /home/branden/share/info/groff.info* for d in doc /tmp/rando/groff-1.25.0.rc2/doc; do \ if [ -f "$d"/groff.info ]; then \ cp "$d"/groff.info* /home/branden/share/info; \ install-info --info-file="$d"/groff.info \ --info-dir=/home/branden/share/info; \ break; \ fi; \ done /home/branden/bin/mkdir -p /home/branden/share/groff/1.25.0/font /home/branden/bin/install -c -m 644 ./src/devices/xditview/FontMap-X11 \ /home/branden/share/groff/1.25.0/font/FontMap-X11 test -d /home/branden/lib/X11/app-defaults \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/lib/X11/app-defaults /home/branden/bin/install -c -m 644 ./src/devices/xditview/GXditview.ad \ /home/branden/lib/X11/app-defaults/GXditview /home/branden/bin/install -c -m 644 ./src/devices/xditview/GXditview-color.ad \ /home/branden/lib/X11/app-defaults/GXditview-color test -d /home/branden/share \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share test -d /home/branden/share/groff \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/groff test -d /home/branden/share/groff/1.25.0 \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/groff/1.25.0 if test -f /usr/lib/eign; then \ rm -f /home/branden/share/groff/1.25.0/eign; \ ln -s /usr/lib/eign /home/branden/share/groff/1.25.0/eign 2>/dev/null \ || ln /usr/lib/eign /home/branden/share/groff/1.25.0/eign 2>/dev/null \ || cp /usr/lib/eign /home/branden/share/groff/1.25.0/eign; \ else \ rm -f /home/branden/share/groff/1.25.0/eign; \ /home/branden/bin/install -c -m 644 ./src/utils/indxbib/eign /home/branden/share/groff/1.25.0/eign; \ fi /home/branden/bin/mkdir -p /home/branden/lib/groff/site-tmac; if test "no" != "no"; then \ if test -n ""; then \ for m in ""; do \ /home/branden/bin/install -c -m 644 tmac/$m-wrap \ /home/branden/lib/groff/site-tmac/$m`if test no = manual; then echo "-os"; fi`.tmac; \ done; \ fi; \ fi /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devX100-12' /home/branden/bin/install -c -m 644 font/devX100-12/DESC font/devX100-12/TR font/devX100-12/TI font/devX100-12/TB font/devX100-12/TBI font/devX100-12/CR font/devX100-12/CI font/devX100-12/CB font/devX100-12/CBI font/devX100-12/HR font/devX100-12/HI font/devX100-12/HB font/devX100-12/HBI font/devX100-12/NR font/devX100-12/NI font/devX100-12/NB font/devX100-12/NBI font/devX100-12/S '/home/branden/share/groff/1.25.0/font/devX100-12' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devX100' /home/branden/bin/install -c -m 644 font/devX100/DESC font/devX100/TR font/devX100/TI font/devX100/TB font/devX100/TBI font/devX100/CR font/devX100/CI font/devX100/CB font/devX100/CBI font/devX100/HR font/devX100/HI font/devX100/HB font/devX100/HBI font/devX100/NR font/devX100/NI font/devX100/NB font/devX100/NBI font/devX100/S '/home/branden/share/groff/1.25.0/font/devX100' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devX75-12' /home/branden/bin/install -c -m 644 font/devX75-12/DESC font/devX75-12/TR font/devX75-12/TI font/devX75-12/TB font/devX75-12/TBI font/devX75-12/CR font/devX75-12/CI font/devX75-12/CB font/devX75-12/CBI font/devX75-12/HR font/devX75-12/HI font/devX75-12/HB font/devX75-12/HBI font/devX75-12/NR font/devX75-12/NI font/devX75-12/NB font/devX75-12/NBI font/devX75-12/S '/home/branden/share/groff/1.25.0/font/devX75-12' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devX75' /home/branden/bin/install -c -m 644 font/devX75/DESC font/devX75/TR font/devX75/TI font/devX75/TB font/devX75/TBI font/devX75/CR font/devX75/CI font/devX75/CB font/devX75/CBI font/devX75/HR font/devX75/HI font/devX75/HB font/devX75/HBI font/devX75/NR font/devX75/NI font/devX75/NB font/devX75/NBI font/devX75/S '/home/branden/share/groff/1.25.0/font/devX75' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devascii' /home/branden/bin/install -c -m 644 font/devascii/R font/devascii/I font/devascii/B font/devascii/BI font/devascii/DESC '/home/branden/share/groff/1.25.0/font/devascii' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devdvi' /home/branden/bin/install -c -m 644 font/devdvi/TR font/devdvi/TI font/devdvi/TB font/devdvi/TBI font/devdvi/CW font/devdvi/CWI font/devdvi/HR font/devdvi/HI font/devdvi/HB font/devdvi/HBI font/devdvi/TREC font/devdvi/TIEC font/devdvi/TBEC font/devdvi/TBIEC font/devdvi/CWEC font/devdvi/CWIEC font/devdvi/HREC font/devdvi/HIEC font/devdvi/HBEC font/devdvi/HBIEC font/devdvi/TRTC font/devdvi/TITC font/devdvi/TBTC font/devdvi/TBITC font/devdvi/CWTC font/devdvi/CWITC font/devdvi/HRTC font/devdvi/HITC font/devdvi/HBTC font/devdvi/HBITC font/devdvi/MI font/devdvi/S font/devdvi/EX font/devdvi/SA font/devdvi/SB font/devdvi/SC font/devdvi/CSH font/devdvi/CSS font/devdvi/CTH font/devdvi/CTS '/home/branden/share/groff/1.25.0/font/devdvi' /home/branden/bin/install -c -m 644 font/devdvi/JPG font/devdvi/JPM font/devdvi/KOG font/devdvi/KOM font/devdvi/DESC '/home/branden/share/groff/1.25.0/font/devdvi' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devdvi/generate' /home/branden/bin/install -c -m 644 font/devdvi/generate/Makefile font/devdvi/generate/msam.map font/devdvi/generate/msbm.map font/devdvi/generate/texb.map font/devdvi/generate/texex.map font/devdvi/generate/texi.map font/devdvi/generate/texmi.map font/devdvi/generate/texr.map font/devdvi/generate/texsy.map font/devdvi/generate/textt.map font/devdvi/generate/textex.map font/devdvi/generate/ec.map font/devdvi/generate/tc.map font/devdvi/generate/CompileFonts '/home/branden/share/groff/1.25.0/font/devdvi/generate' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devhtml' /home/branden/bin/install -c -m 644 font/devhtml/R font/devhtml/I font/devhtml/B font/devhtml/BI font/devhtml/CR font/devhtml/CI font/devhtml/CB font/devhtml/CBI font/devhtml/S font/devhtml/CSH font/devhtml/CSS font/devhtml/CTH font/devhtml/CTS font/devhtml/JPG font/devhtml/JPM font/devhtml/KOG font/devhtml/KOM font/devhtml/DESC '/home/branden/share/groff/1.25.0/font/devhtml' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devlatin1' /home/branden/bin/install -c -m 644 font/devlatin1/R font/devlatin1/I font/devlatin1/B font/devlatin1/BI font/devlatin1/DESC '/home/branden/share/groff/1.25.0/font/devlatin1' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devlbp' /home/branden/bin/install -c -m 644 font/devlbp/HB font/devlbp/HBI font/devlbp/HI font/devlbp/HR font/devlbp/HNB font/devlbp/HNBI font/devlbp/HNI font/devlbp/HNR font/devlbp/TB font/devlbp/TBI font/devlbp/TI font/devlbp/TR font/devlbp/CR font/devlbp/CB font/devlbp/CI font/devlbp/ER font/devlbp/EB font/devlbp/EI font/devlbp/DESC '/home/branden/share/groff/1.25.0/font/devlbp' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devpdf' /home/branden/bin/install -c -m 644 font/devpdf/S font/devpdf/ZD font/devpdf/CB font/devpdf/CBI font/devpdf/CI font/devpdf/CR font/devpdf/HB font/devpdf/HBI font/devpdf/HI font/devpdf/HR font/devpdf/TB font/devpdf/TBI font/devpdf/TI font/devpdf/TR font/devpdf/EURO font/devpdf/AB font/devpdf/ABI font/devpdf/AI font/devpdf/AR font/devpdf/BMB font/devpdf/BMBI font/devpdf/BMI font/devpdf/BMR font/devpdf/HNB font/devpdf/HNBI font/devpdf/HNI font/devpdf/HNR font/devpdf/NB font/devpdf/NBI font/devpdf/NI font/devpdf/NR font/devpdf/PB font/devpdf/PBI font/devpdf/PI font/devpdf/PR font/devpdf/ZCMI font/devpdf/U-S font/devpdf/U-ZD font/devpdf/U-ZCMI font/devpdf/U-AB '/home/branden/share/groff/1.25.0/font/devpdf' /home/branden/bin/install -c -m 644 font/devpdf/U-ABI font/devpdf/U-AI font/devpdf/U-AR font/devpdf/U-BMB font/devpdf/U-BMBI font/devpdf/U-BMI font/devpdf/U-BMR font/devpdf/U-CB font/devpdf/U-CBI font/devpdf/U-CI font/devpdf/U-CR font/devpdf/U-HB font/devpdf/U-HBI font/devpdf/U-HI font/devpdf/U-HR font/devpdf/U-HNB font/devpdf/U-HNBI font/devpdf/U-HNI font/devpdf/U-HNR font/devpdf/U-NB font/devpdf/U-NBI font/devpdf/U-NI font/devpdf/U-NR font/devpdf/U-PB font/devpdf/U-PBI font/devpdf/U-PI font/devpdf/U-PR font/devpdf/U-TB font/devpdf/U-TBI font/devpdf/U-TI font/devpdf/U-TR font/devpdf/DESC font/devpdf/SS font/devpdf/symbolsl.afm font/devpdf/symbolsl.pfb font/devpdf/download font/devpdf/Foundry '/home/branden/share/groff/1.25.0/font/devpdf' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devpdf/enc' /home/branden/bin/install -c -m 644 font/devpdf/enc/text.enc '/home/branden/share/groff/1.25.0/font/devpdf/enc' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devpdf/map' /home/branden/bin/install -c -m 644 font/devpdf/map/dingbats.map font/devpdf/map/symbol.map font/devpdf/map/text.map '/home/branden/share/groff/1.25.0/font/devpdf/map' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devutf8' /home/branden/bin/install -c -m 644 font/devutf8/R font/devutf8/I font/devutf8/B font/devutf8/BI font/devutf8/CSH font/devutf8/CSS font/devutf8/CTH font/devutf8/CTS font/devutf8/JPG font/devutf8/JPM font/devutf8/KOG font/devutf8/KOM font/devutf8/DESC '/home/branden/share/groff/1.25.0/font/devutf8' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples/chem' /home/branden/bin/install -c -m 644 contrib/chem/examples/README contrib/chem/examples/atp.chem contrib/chem/examples/cholesterol.chem contrib/chem/examples/ethamivan.chem contrib/chem/examples/lsd.chem contrib/chem/examples/mepacrine.chem contrib/chem/examples/morphine.chem contrib/chem/examples/penicillin.chem contrib/chem/examples/reserpine.chem '/home/branden/share/doc/groff-1.25.0/examples/chem' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 ./contrib/chem/chem.pic '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devlj4' /home/branden/bin/install -c -m 644 font/devlj4/AB font/devlj4/ABI font/devlj4/AI font/devlj4/AR font/devlj4/ALBB font/devlj4/ALBR font/devlj4/AOB font/devlj4/AOI font/devlj4/AOR font/devlj4/CB font/devlj4/CBI font/devlj4/CI font/devlj4/CR font/devlj4/GB font/devlj4/GBI font/devlj4/GI font/devlj4/GR font/devlj4/LGB font/devlj4/LGI font/devlj4/LGR font/devlj4/OB font/devlj4/OBI font/devlj4/OI font/devlj4/OR font/devlj4/TB font/devlj4/TBI font/devlj4/TI font/devlj4/TR font/devlj4/TNRB font/devlj4/TNRBI font/devlj4/TNRI font/devlj4/TNRR font/devlj4/UB font/devlj4/UBI font/devlj4/UI font/devlj4/UR font/devlj4/UCB font/devlj4/UCBI font/devlj4/UCI font/devlj4/UCR '/home/branden/share/groff/1.25.0/font/devlj4' /home/branden/bin/install -c -m 644 font/devlj4/CLARENDON font/devlj4/CORONET font/devlj4/MARIGOLD font/devlj4/S font/devlj4/SYMBOL font/devlj4/WINGDINGS '/home/branden/share/groff/1.25.0/font/devlj4' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devlj4/generate' /home/branden/bin/install -c -m 644 font/devlj4/generate/Makefile font/devlj4/generate/special.map font/devlj4/generate/symbol.map font/devlj4/generate/text.map font/devlj4/generate/wingdings.map font/devlj4/generate/special.awk '/home/branden/share/groff/1.25.0/font/devlj4/generate' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devps' /home/branden/bin/install -c -m 644 font/devps/S font/devps/SS font/devps/ZD font/devps/ZDR font/devps/ZCMI font/devps/AB font/devps/ABI font/devps/AI font/devps/AR font/devps/BMB font/devps/BMBI font/devps/BMI font/devps/BMR font/devps/CB font/devps/CBI font/devps/CI font/devps/CR font/devps/HB font/devps/HBI font/devps/HI font/devps/HR font/devps/HNB font/devps/HNBI font/devps/HNI font/devps/HNR font/devps/NB font/devps/NBI font/devps/NI font/devps/NR font/devps/PB font/devps/PBI font/devps/PI font/devps/PR font/devps/TB font/devps/TBI font/devps/TI font/devps/TR font/devps/EURO font/devps/CSH font/devps/CSS '/home/branden/share/groff/1.25.0/font/devps' /home/branden/bin/install -c -m 644 font/devps/CTH font/devps/CTS font/devps/JPG font/devps/JPM font/devps/KOG font/devps/KOM font/devps/freeeuro.afm font/devps/symbolsl.afm font/devps/text.enc font/devps/zapfdr.afm font/devps/download '/home/branden/share/groff/1.25.0/font/devps' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devps/generate' /home/branden/bin/install -c -m 644 font/devps/generate/Makefile font/devps/generate/dingbats.map font/devps/generate/dingbats-reversed.map font/devps/generate/slanted-symbol.map font/devps/generate/symbol.map font/devps/generate/symbolsl.awk font/devps/generate/text.map font/devps/generate/afmname font/devps/generate/symbol.sed '/home/branden/share/groff/1.25.0/font/devps/generate' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples' /home/branden/bin/install -c -m 644 doc/webpage.ms doc/groff.css doc/grnexmpl.g doc/grnexmpl.me '/home/branden/share/doc/groff-1.25.0/examples' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/eqnrc '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/dvi.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/lbp.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/lj4.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/pdf.tmac tmac/pdfpic.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/europs.tmac tmac/ps.tmac tmac/psatk.tmac tmac/psfig.tmac tmac/psold.tmac tmac/pspic.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/tty.tmac tmac/tty-char.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples/hdtbl' /home/branden/bin/install -c -m 644 contrib/hdtbl/examples/common.roff contrib/hdtbl/examples/chess_board.roff contrib/hdtbl/examples/color_boxes.roff contrib/hdtbl/examples/color_nested_tables.roff contrib/hdtbl/examples/color_table_cells.roff contrib/hdtbl/examples/color_transitions.roff contrib/hdtbl/examples/col_rowspan_colors.roff contrib/hdtbl/examples/mixed_pickles.roff contrib/hdtbl/examples/rainbow.roff contrib/hdtbl/examples/short_reference.roff '/home/branden/share/doc/groff-1.25.0/examples/hdtbl' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 contrib/hdtbl/hdtbl.tmac contrib/hdtbl/hdmisc.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples' /home/branden/bin/install -c -m 644 contrib/install-font/install-font.bash '/home/branden/share/doc/groff-1.25.0/examples' /home/branden/bin/mkdir -p '/home/branden/share/groff/site-tmac' /home/branden/bin/install -c -m 644 tmac/man.local tmac/mdoc.local '/home/branden/share/groff/site-tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac/mdoc' /home/branden/bin/install -c -m 644 tmac/mdoc/doc-common tmac/mdoc/doc-ditroff tmac/mdoc/doc-nroff tmac/mdoc/doc-syms '/home/branden/share/groff/1.25.0/tmac/mdoc' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac/mm' /home/branden/bin/install -c -m 644 contrib/mm/mm/0.MT contrib/mm/mm/5.MT contrib/mm/mm/4.MT contrib/mm/mm/ms.cov contrib/mm/mm/se_ms.cov '/home/branden/share/groff/1.25.0/tmac/mm' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples/mm' /home/branden/bin/install -c -m 644 contrib/mm/examples/letter.mm contrib/mm/examples/memorandum.mm contrib/mm/examples/story.mm '/home/branden/share/doc/groff-1.25.0/examples/mm' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples/mom' /home/branden/bin/install -c -m 644 contrib/mom/examples/letter.mom contrib/mom/examples/mom-pdf.mom contrib/mom/examples/mon_premier_doc.mom contrib/mom/examples/sample_docs.mom contrib/mom/examples/typesetting.mom contrib/mom/examples/README.txt contrib/mom/examples/README-fr.txt contrib/mom/examples/elvis_syntax contrib/mom/examples/elvis_syntax.new contrib/mom/examples/penguin.ps contrib/mom/examples/penguin.pdf contrib/mom/examples/mom.vim contrib/mom/examples/slide-demo.mom contrib/mom/examples/copyright-default.mom contrib/mom/examples/copyright-chapter.mom '/home/branden/share/doc/groff-1.25.0/examples/mom' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 contrib/mom/mom.tmac contrib/mom/om.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/oldfont/devps' /home/branden/bin/install -c -m 644 font/devps/old/S font/devps/old/SS font/devps/old/CB font/devps/old/CBI font/devps/old/CI font/devps/old/CR font/devps/old/HB font/devps/old/HBI font/devps/old/HI font/devps/old/HR font/devps/old/HNB font/devps/old/HNBI font/devps/old/HNI font/devps/old/HNR font/devps/old/NB font/devps/old/NBI font/devps/old/NI font/devps/old/NR font/devps/old/PB font/devps/old/PBI font/devps/old/PI font/devps/old/PR font/devps/old/TB font/devps/old/TBI font/devps/old/TI font/devps/old/TR font/devps/old/symbol.afm font/devps/old/symbolsl.afm font/devps/old/zapfdr.afm font/devps/old/zapfdr.ps '/home/branden/share/groff/1.25.0/oldfont/devps' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0' /home/branden/bin/install -c -m 644 doc/me-revisions doc/pic.ms doc/groff-pdf-features.ms '/home/branden/share/doc/groff-1.25.0' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/pic.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/html.tmac tmac/html-end.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/refer.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 contrib/rfc1345/rfc1345.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 contrib/sboxes/sboxes.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/man.tmac tmac/mandoc.tmac tmac/andoc.tmac tmac/an-ext.tmac tmac/ms.tmac tmac/e.tmac tmac/me.tmac tmac/doc-old.tmac tmac/doc.tmac tmac/mdoc.tmac tmac/papersize.tmac tmac/62bit.tmac tmac/ec.tmac tmac/trace.tmac tmac/ptx.tmac tmac/latin1.tmac tmac/latin2.tmac tmac/latin5.tmac tmac/latin9.tmac tmac/koi8-r.tmac tmac/X.tmac tmac/Xps.tmac tmac/devtag.tmac tmac/composite.tmac tmac/fallbacks.tmac tmac/refer-me.tmac tmac/refer-ms.tmac tmac/troffrc tmac/troffrc-end tmac/trans.tmac tmac/en.tmac tmac/hyphen.en tmac/hyphenex.en tmac/es.tmac tmac/hyphen.es tmac/fr.tmac tmac/hyphen.fr tmac/it.tmac tmac/hyphen.it tmac/pl.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/hyphen.pl tmac/ru.tmac tmac/hyphen.ru tmac/sv.tmac tmac/hyphen.sv tmac/de.tmac tmac/den.tmac tmac/hyphen.det tmac/hyphen.den tmac/cs.tmac tmac/hyphen.cs tmac/hyphenex.cs tmac/ja.tmac tmac/zh.tmac tmac/an.tmac tmac/s.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 contrib/mm/refer-mm.tmac '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/html' /home/branden/bin/install -c -m 644 doc/pic.html '/home/branden/share/doc/groff-1.25.0/html' /home/branden/bin/mkdir -p '/home/branden/share/man/man1' /home/branden/bin/install -c -m 644 contrib/chem/chem.1 contrib/eqn2graph/eqn2graph.1 contrib/gdiffmk/gdiffmk.1 contrib/glilypond/glilypond.1 contrib/gperl/gperl.1 contrib/gpinyin/gpinyin.1 contrib/grap2graph/grap2graph.1 contrib/mm/mmroff.1 contrib/pic2graph/pic2graph.1 src/devices/grodvi/grodvi.1 src/devices/grohtml/grohtml.1 src/devices/grolbp/grolbp.1 src/devices/grolj4/grolj4.1 src/devices/gropdf/gropdf.1 src/devices/grops/grops.1 src/devices/grotty/grotty.1 src/devices/xditview/gxditview.1 src/preproc/preconv/preconv.1 src/roff/groff/groff.1 src/utils/addftinfo/addftinfo.1 src/utils/afmtodit/afmtodit.1 src/utils/grog/grog.1 src/utils/hpftodit/hpftodit.1 src/utils/lkbib/lkbib.1 src/utils/pdfmom/pdfmom.1 src/utils/pfbtops/pfbtops.1 src/utils/tfmtodit/tfmtodit.1 src/utils/xtotroff/xtotroff.1 src/preproc/eqn/eqn.1 src/preproc/eqn/neqn.1 src/preproc/grn/grn.1 src/preproc/pic/pic.1 src/preproc/refer/refer.1 src/preproc/soelim/soelim.1 src/preproc/tbl/tbl.1 src/roff/nroff/nroff.1 src/roff/troff/troff.1 src/utils/indxbib/indxbib.1 src/utils/lookbib/lookbib.1 '/home/branden/share/man/man1' /home/branden/bin/mkdir -p '/home/branden/share/man/man5' /home/branden/bin/install -c -m 644 man/groff_font.5 man/groff_out.5 man/groff_tmac.5 '/home/branden/share/man/man5' /home/branden/bin/mkdir -p '/home/branden/share/man/man7' /home/branden/bin/install -c -m 644 contrib/hdtbl/groff_hdtbl.7 contrib/mm/groff_mm.7 contrib/mm/groff_mmse.7 contrib/mom/groff_mom.7 contrib/rfc1345/groff_rfc1345.7 man/groff_char.7 man/groff_diff.7 man/groff.7 man/roff.7 tmac/groff_ms.7 tmac/groff_man.7 tmac/groff_man_style.7 tmac/groff_me.7 tmac/groff_mdoc.7 tmac/groff_trace.7 tmac/groff_www.7 '/home/branden/share/man/man7' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/html/mom' /home/branden/bin/install -c -m 644 contrib/mom/momdoc/stylesheet.css contrib/mom/momdoc/appendices.html contrib/mom/momdoc/color.html contrib/mom/momdoc/cover.html contrib/mom/momdoc/definitions.html contrib/mom/momdoc/docelement.html contrib/mom/momdoc/docprocessing.html contrib/mom/momdoc/goodies.html contrib/mom/momdoc/graphical.html contrib/mom/momdoc/headfootpage.html contrib/mom/momdoc/images.html contrib/mom/momdoc/inlines.html contrib/mom/momdoc/intro.html contrib/mom/momdoc/letters.html contrib/mom/momdoc/macrolist.html contrib/mom/momdoc/rectoverso.html contrib/mom/momdoc/refer.html contrib/mom/momdoc/reserved.html contrib/mom/momdoc/tables-of-contents.html contrib/mom/momdoc/toc.html contrib/mom/momdoc/typesetting.html contrib/mom/momdoc/using.html contrib/mom/momdoc/version-2.html '/home/branden/share/doc/groff-1.25.0/html/mom' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devlj4' /home/branden/bin/install -c -m 644 font/devlj4/DESC '/home/branden/share/groff/1.25.0/font/devlj4' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/font/devps' /home/branden/bin/install -c -m 644 font/devps/DESC font/devps/prologue font/devps/freeeuro.pfa font/devps/zapfdr.pfa font/devps/symbolsl.pfa '/home/branden/share/groff/1.25.0/font/devps' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples' /home/branden/bin/install -c -m 644 doc/webpage.html doc/webpage.ps doc/grnexmpl.ps '/home/branden/share/doc/groff-1.25.0/examples' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/pdf' /home/branden/bin/install -c -m 644 doc/automake.pdf doc/groff-man-pages.pdf doc/ms.pdf doc/pic.pdf doc/groff-pdf-features.pdf '/home/branden/share/doc/groff-1.25.0/pdf' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples/hdtbl' /home/branden/bin/install -c -m 644 contrib/hdtbl/examples/fonts_n.roff contrib/hdtbl/examples/fonts_x.roff contrib/hdtbl/examples/chess_board.ps contrib/hdtbl/examples/color_boxes.ps contrib/hdtbl/examples/color_nested_tables.ps contrib/hdtbl/examples/color_table_cells.ps contrib/hdtbl/examples/color_transitions.ps contrib/hdtbl/examples/col_rowspan_colors.ps contrib/hdtbl/examples/fonts_n.ps contrib/hdtbl/examples/fonts_x.ps contrib/hdtbl/examples/mixed_pickles.ps contrib/hdtbl/examples/rainbow.ps contrib/hdtbl/examples/short_reference.ps doc/gnu.eps '/home/branden/share/doc/groff-1.25.0/examples/hdtbl' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/examples/mom' /home/branden/bin/install -c -m 644 contrib/mom/examples/letter.pdf contrib/mom/examples/mom-pdf.pdf contrib/mom/examples/mon_premier_doc.pdf contrib/mom/examples/sample_docs.pdf contrib/mom/examples/slide-demo.pdf contrib/mom/examples/copyright-default.pdf contrib/mom/examples/copyright-chapter.pdf contrib/mom/examples/typesetting.pdf '/home/branden/share/doc/groff-1.25.0/examples/mom' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0' /home/branden/bin/install -c -m 644 doc/meref.ps doc/meintro.ps doc/meintro_fr.ps doc/groff-man-pages.utf8.txt doc/meintro.me doc/meintro_fr.me doc/meref.me doc/ms.ms '/home/branden/share/doc/groff-1.25.0' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0' /home/branden/bin/install -c -m 644 contrib/sboxes/msboxes.ms '/home/branden/share/doc/groff-1.25.0' /home/branden/bin/mkdir -p '/home/branden/share/doc/groff-1.25.0/pdf' /home/branden/bin/install -c -m 644 contrib/sboxes/msboxes.pdf '/home/branden/share/doc/groff-1.25.0/pdf' /home/branden/bin/mkdir -p '/home/branden/share/groff/1.25.0/tmac' /home/branden/bin/install -c -m 644 tmac/www.tmac '/home/branden/share/groff/1.25.0/tmac' make install-data-hook make[4]: Entering directory '/tmp/rando/groff-1.25.0.rc2' for f in mom-pdf.pdf; do \ rm -f /home/branden/share/doc/groff-1.25.0/pdf/$f; \ ln -s /home/branden/share/doc/groff-1.25.0/examples/mom/$f /home/branden/share/doc/groff-1.25.0/pdf/$f; \ done cd doc \ && for f in `ls pic*.html`; do \ rm -f /home/branden/share/doc/groff-1.25.0/html/$f; \ /home/branden/bin/install -c -m 644 $f /home/branden/share/doc/groff-1.25.0/html/$f; \ done test -d /home/branden/share/doc/groff-1.25.0/html/img \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/doc/groff-1.25.0/html/img rm -f /home/branden/share/doc/groff-1.25.0/html/img/pic* /home/branden/bin/install -c -m 644 doc/img/pic* \ /home/branden/share/doc/groff-1.25.0/html/img for d in doc /tmp/rando/groff-1.25.0.rc2/doc; do \ if test -f "$d/gnu.eps"; then \ rm -f /home/branden/share/doc/groff-1.25.0/examples/gnu.eps; \ /home/branden/bin/install -c -m 644 \ $d/gnu.eps /home/branden/share/doc/groff-1.25.0/examples/gnu.eps; \ break; \ fi; \ done for d in doc /tmp/rando/groff-1.25.0.rc2/doc; do \ if test -f "$d/gnu.png"; then \ rm -f /home/branden/share/doc/groff-1.25.0/examples/gnu.png; \ /home/branden/bin/install -c -m 644 \ $d/gnu.png /home/branden/share/doc/groff-1.25.0/examples/gnu.png; \ break; \ fi; \ done cd doc \ && for f in `ls webpage*.html`; do \ rm -f /home/branden/share/doc/groff-1.25.0/examples/$f; \ /home/branden/bin/install -c -m 644 $f /home/branden/share/doc/groff-1.25.0/examples/$f; \ done test -d /home/branden/share/doc/groff-1.25.0/examples/img \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/doc/groff-1.25.0/examples/img rm -f \ /home/branden/share/doc/groff-1.25.0/examples/img/webpage* /home/branden/bin/install -c -m 644 doc/img/webpage* \ /home/branden/share/doc/groff-1.25.0/examples/img if test "no" = "yes"; then \ if test -n ""; then \ if test -f /home/branden/share/groff/1.25.0/tmac/s.tmac -a -n "`if test no = yes; then for i in ""; do case "$i" in s) echo g;; esac; done; fi`"; \ then \ mv /home/branden/share/groff/1.25.0/tmac/s.tmac \ /home/branden/share/groff/1.25.0/tmac/`if test no = yes; then for i in ""; do case "$i" in s) echo g;; esac; done; fi`s.tmac; \ fi; \ if test -f /home/branden/share/groff/1.25.0/tmac/an.tmac -a -n "`if test no = yes; then for i in ""; do case "$i" in an) echo g;; esac; done; fi`"; \ then \ mv /home/branden/share/groff/1.25.0/tmac/an.tmac \ /home/branden/share/groff/1.25.0/tmac/`if test no = yes; then for i in ""; do case "$i" in an) echo g;; esac; done; fi`an.tmac; \ fi; \ fi; \ fi cd /home/branden/share/groff; \ rm -f current; \ ln -s 1.25.0 current test -d /home/branden/share/groff/site-font \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/share/groff/site-font test -d /home/branden/lib/groff/site-tmac \ || /bin/bash /tmp/rando/groff-1.25.0.rc2/build-aux/install-sh -d /home/branden/lib/groff/site-tmac make[4]: Leaving directory '/tmp/rando/groff-1.25.0.rc2' make[3]: Leaving directory '/tmp/rando/groff-1.25.0.rc2' make[2]: Leaving directory '/tmp/rando/groff-1.25.0.rc2' make[1]: Leaving directory '/tmp/rando/groff-1.25.0.rc2' ## 2026-08-23 09:06:12 bash-5.1 [8] {0} (0) branden@illithid:/tmp/rando/groff-1.25.0.rc2 !986$ [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 14:16 ` G. Branden Robinson @ 2026-08-23 15:06 ` Alejandro Colomar 2026-08-23 16:44 ` G. Branden Robinson 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-23 15:06 UTC (permalink / raw) To: G. Branden Robinson; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 5776 bytes --] Hi Branden, > Date: 2026-08-23 09:16:22-0500 > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > Hi Alex, > > At 2026-08-23T15:55:29+0200, Alejandro Colomar wrote: > > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > > > Do you know what's wrong? > > > > > > More or less. It turns out to be damned hard to balance the > > > requirements of (1) Automake maintainer mode; (2) building from Git > > > repository checkouts; and (3) building from distribution archives. > > > Bruno Haible has been helpful in finding scenarios that don't work. > > > > > > https://lists.gnu.org/archive/html/groff/2026-08/msg00039.html > > > > Hmmmm, now it rings a bell. bootstrap said something about configure > > with maintainer mode, but I ignored that, since I had never used > > maintainer mode. > > Right. I introduced that very recently during the RCs for 1.25.0, > because it seemed necessary. But as shown, Bruno has proposed patches > ripping it back out. > > I'm pretty frustrated with Automake's lack of explicit support for > building from Git working copies. Or maybe it's brilliantly documented > somewhere I haven't seen yet... I dislike autotools for that and other reasons. For groff(1), writing a portable hand-written Makefile might be too hard to write. But for the man-pages, I love the hand-written Makefile we have. I'm still waiting for GNU Make to make a new release, and then be able to get rid of the mandatory -R, but other than that, it works quite nicely. [...] > I do _not_ get such errors. Shell session attached. > > ...but I'm building _from the release candidate archive_, as I advised > you to do. Yup; I don't like using tarballs. It's much easier to just check out git HEAD. :) > > > Build finished successfully for me in about 60 seconds. > > > > Out of curiosity, where did you get those timestamps from? Does your > > history file store them? > > Yes. That's simply the output of Bash's "history" built-in. I chopped > off the command numbers and removed irrelevancies like "ls". Oh, I don't have that! $ history | tail -n1 1997 history | tail -n1 After checking `help history`, I now realize it has a HISTTIMEFORMAT variable for doing that. I've added it now to my bashrc: alx@devuan:~/src/alx/config/main$ git show -U0 commit 9b64c78f797fc3abab83148b24143402a5d2a839 (HEAD -> main) Author: Alejandro Colomar <alx@kernel.org> Date: 2026-08-23 16:53:59 +0200 bash: HISTTIMEFORMAT: Add variable Signed-off-by: Alejandro Colomar <alx@kernel.org> diff --git a/etc/bash.bashrc b/etc/bash.bashrc index af974d211e14..f2f7772c8e51 100644 --- a/etc/bash.bashrc +++ b/etc/bash.bashrc @@ -2,0 +3 @@ export GPG_TTY="$(tty)"; +export HISTTIMEFORMAT="%F %T%z "; I've been wanting that for a long long time! It's good to know it exists. :) > > Using groff from git HEAD, I see the list as this: > > > > $ cat ls.man > > .TH a s d f > > .SH test > > foo > > .LS > > .IP \[bu] 3 > > bar > > .IP \[bu] > > baz > > .LS > > .P > > qwe > > $ /opt/local/gnu/groff/20260823_master/bin/groff -man -Tutf8 ./ls.man > > a(s) a(s) > > > > test > > foo > > > > • bar > > > > • baz > > > > qwe > > > > f d a(s) > > > > Is this intended? I thought it would imply PD 0. > > Yes, it's intended. If you want the list compact, you have to say so. > > Also, you need to say what kind of list you're presenting. > > groff_man(7): > .LS type [compactness [indentation]] > (since groff 1.25) Start (or open) a list. type is one of > “definition”, “enumerated”, or “itemized”. compactness is a > Boolean value directing suppression of inter‐paragraph > spacing between list items. indentation specifies an > indentation amount for the body of each list item; it is > then unnecessary to specify this argument to the list item > macros. Use IP with a mark argument to represent an > itemized or enumerated list item, and TP for a definition > list item. Use IP without arguments to associate successive > paragraphs with an existing list item; to these, inter‐ > paragraph spacing applies even in compact lists. > > .LE (since groff 1.25) End (or close) the most recent open list. > > > .LS > > Say instead: > > .LS itemized 1 Oh, yeah, I forgot to RTFM. :-) Here's an interesting thing (it might be okay, just noting it): diff --git i/man/man5/tunables.conf.5 w/man/man5/tunables.conf.5 index 91bb6b81cb85..835c409eb074 100644 --- i/man/man5/tunables.conf.5 +++ w/man/man5/tunables.conf.5 @@ -89,9 +89,10 @@ .SS Filters Filters limit the tunables following it. The effects of a filter are terminated by any of the following: +.P +.LS itemized 1 .IP \[bu] 3 The end of the file. -.PD 0 .IP \[bu] The end of an included file. .IP \[bu] @@ -100,7 +101,7 @@ .SS Filters directive. .IP \[bu] A new (possibly empty) filter. -.PD +.LE .P The syntax is: .P I had to add that P paragraph so that there's a blank before the list. That's a bit unusual, since that would technically be an empty paragraph; or maybe we can consider that paragraph to be the entire list, but that's unusual in man(7). That said, I'm fine with that. What do you think? Cheers, Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 15:06 ` Alejandro Colomar @ 2026-08-23 16:44 ` G. Branden Robinson 2026-08-23 19:30 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: G. Branden Robinson @ 2026-08-23 16:44 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man, groff [-- Attachment #1: Type: text/plain, Size: 12870 bytes --] [looping in groff list because Alex brought to my attention an item of work on the new man(7) `LS` and `LE` macros that needs to be done] Hi Alex, At 2026-08-23T17:06:16+0200, Alejandro Colomar wrote: > > Date: 2026-08-23 09:16:22-0500 > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > At 2026-08-23T15:55:29+0200, Alejandro Colomar wrote: > > > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > > > > Do you know what's wrong? > > > > More or less. It turns out to be damned hard to balance the > > > > requirements of (1) Automake maintainer mode; (2) building from > > > > Git repository checkouts; and (3) building from distribution > > > > archives. Bruno Haible has been helpful in finding scenarios > > > > that don't work. > > > > > > > > https://lists.gnu.org/archive/html/groff/2026-08/msg00039.html > > > > > > Hmmmm, now it rings a bell. bootstrap said something about > > > configure with maintainer mode, but I ignored that, since I had > > > never used maintainer mode. > > > > Right. I introduced that very recently during the RCs for 1.25.0, > > because it seemed necessary. But as shown, Bruno has proposed > > patches ripping it back out. > > > > I'm pretty frustrated with Automake's lack of explicit support for > > building from Git working copies. Or maybe it's brilliantly > > documented somewhere I haven't seen yet... > > I dislike autotools for that and other reasons. Autoconf, Automake, and Libtool, the collective "autotools", are all strongly distinguishable in purpose. Autoconf is a brilliant idea, very well executed. I suspect that many of its its detractors possess a constellation of negative traits: 1. They're not terribly competent at writing portable shell scripts; 2. they refuse to understand the very simple principle of operation of the m4 macro language; and 3. they refuse to believe that the variety of possible deployment environments is as wide as it is. To be fair, employers in the tech sector tend to pursue the correction of none of these flaws. Shell scripting is not widely recognized as being as demanding a discipline as it is, I suspect because a whole generation of engineering managers got hired from Microsoft shops; these people understood what an MS-DOS batch file was, and grasped that a Unix shell script was the analogue. What do you use batch files for? How hard could any of this be? That cohort of managers is likely in retirement now, but they passed their "wisdom" to their successors via the usual channels through which managerial class expertise transmits. Well, it turns out that statically parsing a POSIX shell script is not a decidable problem.[1] When you find a manager who understands what that _means_, let alone grasps its implications, mark your calendar. Ambitious managers reject such claims outright. They understand that their personal advancement demands profession of the Friedman Doctrine: the social responsibility of the firm is to deliver value (returns) to shareholders. Thus, _all_ problems are decidable--all that is required is sufficient application of one's Nietzschean Will. A software engineer attends school to learn complexity theory, and then is paid a salary in the workforce to forget it. I was intimidated by the idea of Autoconf macros at first. I needn't have been. I already had many years of shell scripting under my belt, and after reading the brief, original m4 paper in Volume 2 of the Version 7 Unix Programmer's Manual,[2] I understood what was going on with the brackets. The mistakes I make when writing Autoconf macros are overwhelmingly logic errors, not struggles with syntax. I'm slowly warming to Automake. I get what it's trying to do. I think it needs better introductory documentation. Libtool is a terrifying solution to a terrifying problem. I'm glad I'll never have to learn anything about it unless I grow the courage to maintain a shared library. I've encountered CMake. It burned me far worse than the Autotools ever have. In my view, rather than being a toolkit with which you can manage your project's build system to your own specifications--meaning that you can _understand_ it--it's a gigantic, baroque DWIM engine that permits a software project to outsource their build system engineering to CMake's maintainers. As always with outsourcing, that'll work great--and managers will love it--until it doesn't. And when it doesn't, people will stumble around, blinking and wondering where to find the expertise they'll need. > For groff(1), writing a portable hand-written Makefile might be too > hard to write. I saw what we had before. Bertrand Garrigues did us an unquestionable service in porting groff to Automake back in 2013/4. > But for the man-pages, I love the hand-written Makefile we have. I, too, love sticking with pure make(1) anywhere I can. POSIX Issue 8 make(1) really allows the tool to shine. I nurse a glimmer of hope that the *BSD Make people can be pressured/ bribed/shamed into supporting pattern rules at long last, and then we'll finally get as close to world peace as is possible. https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/doc/doc.am?h=1.24.1#n310 That's an exhibit of an extremely stupid, and extremely old, problem that I defy any BSD partisan to defend. > I'm still waiting for GNU Make to make a new release, and then be able > to get rid of the mandatory -R, but other than that, it works quite > nicely. Hmm, no release since 4.4 on Halloween 2022. Yeah, they might be due. > Yup; I don't like using tarballs. It's much easier to just check out > git HEAD. :) Yes, but the tarballs get tested in a greater diversity of environments. While I keep git HEAD "green"--I don't "git push" unless "make distcheck" runs successfully--that applies only to my personal development environment. groff doesn't have a CI infrastructure. The build system is the thing that consistently gives us the most pain when trying to firm up a release. So right now you are pulling on HEAD at its most fragile, ironically. The code quality should be good, _if_ you can get the build to completion. > > > > Build finished successfully for me in about 60 seconds. > > > > > > Out of curiosity, where did you get those timestamps from? Does > > > your history file store them? > > > > Yes. That's simply the output of Bash's "history" built-in. I > > chopped off the command numbers and removed irrelevancies like "ls". > > Oh, I don't have that! > > $ history | tail -n1 > 1997 history | tail -n1 > > After checking `help history`, I now realize it has a HISTTIMEFORMAT > variable for doing that. Ah! I completely forgot that I had customized that in my .bashrc. > I've been wanting that for a long long time! It's good to know it > exists. :) Yup. Lots of goodies in Bash. > Oh, yeah, I forgot to RTFM. :-) > > Here's an interesting thing (it might be okay, just noting it): > > diff --git i/man/man5/tunables.conf.5 w/man/man5/tunables.conf.5 > index 91bb6b81cb85..835c409eb074 100644 > --- i/man/man5/tunables.conf.5 > +++ w/man/man5/tunables.conf.5 > @@ -89,9 +89,10 @@ .SS Filters > Filters limit the tunables following it. > The effects of a filter are terminated by > any of the following: > +.P > +.LS itemized 1 > .IP \[bu] 3 > The end of the file. > -.PD 0 > .IP \[bu] > The end of an included file. > .IP \[bu] > @@ -100,7 +101,7 @@ .SS Filters > directive. > .IP \[bu] > A new (possibly empty) filter. > -.PD > +.LE > .P > The syntax is: > .P > > I had to add that P paragraph so that there's a blank before the list. > That's a bit unusual, since that would technically be an empty > paragraph; or maybe we can consider that paragraph to be the entire > list, but that's unusual in man(7). That said, I'm fine with that. > > What do you think? I agree that it looks a little funny; if one imagines the `LS` call as not being there at all, it looks truly redundant, and "mandoc -T lint" will likely complain about it. However, you have to remember that *roff documents are not truly block-structured. mandoc(1) really badly wants them to be, so it pretends that they are, and that sometimes leads it to jump through hoops...or to arguments between groff and mandoc maintainers. ;-) In *roffs, paragraphing macros mean "break for paragraph here", not "paragraph opens here". So, in the foregoing, given that you _want_ inter-paragraph spacing before you start the compact list, the "isolated" `P` makes perfect sense. I think it would be unwise to force a compact list to not be compact prior to its first item, because doing that would foreclose the following sort of layout. (But I see a complementary problem.) $ cat ATTIC/inline-compact-list.man .TH foo 1 2026-08-23 "groff test suite" .SH Name foo \- frobnicate a bar .SH Description This is my man page. There are many like it, but this one is mine. People should read more about .LS itemized 1 4n .IP \[bu] bash .IP \[bu] m4 .IP \[bu] make .P .LE and learn what these tools can do for them. $ nroff -rLL=72n -man ATTIC/inline-compact-list.man foo(1) General Commands Manual foo(1) Name foo - frobnicate a bar Description This is my man page. There are many like it, but this one is mine. People should read more about • bash • m4 • make and learn what these tools can do for them. groff test suite 2026‐08‐23 foo(1) So there is a post-compact list space challenge. You don't want an "empty" `IP` call prior to the `LE`--that will cause unwanted indentation of "and learn...". Maybe `LE` needs to accept an argument applying post-list space (and suppress it if the argument absent). And maybe `LS` needs to accept another argument applying pre-list space (and suppress it if the argument is absent). I'll dig into this. I might switch those defaults around; the objective is to have `LS` and `LE` slot into existing man(7) documents as unobtrusively as possible. As the "NEWS" file says: Because these macros format no text, documents employing them risk no damage to their content if the formatter does not support them. A man(7) document author can choose either to transition to these macros, to manage list "compactness" and item indentation with existing man(7) package facilities, or to employ both approaches. Another governing principle is "man(7) document authors should not have to use *roff requests".[3] groff_man_style(7): Portability ... In roff systems, elemental functions called requests and escape sequences control formatting operations. A request appears on a control line. An escape sequence starts with a backslash (\) and can appear almost anywhere. However, use of roff requests (apart from the empty request “.”) risks poor rendering when a page is processed by non‐roff formatters that attempt to interpret page sources. (Historically, this was commonly attempted for HTML conversion.) Many of these programs don’t interpret the full roff language (let alone extensions): they may be incapable of handling numeric expressions, control structures, or register, string, and macro definitions, causing a document’s contents to be omitted or presented incomprehensibly. If your document uses formatter requests, or escape sequences not shown below, it accepts responsibility for restoring formatter state to what the man macro package expects. So I'll see what I can figure out with those lodestars in sight. An idea involving only compact lists and `sp` and `ns` requests is forming already. I think I might profitably use them in the `LS` and `LE` macro definitions, respectively. The foregoing example will likely spawn an automated test. Thanks for putting groff pre-1.25 to the test! Regards, Branden [1] https://www.irif.fr/~treinen/publi/slides/minidebconf18.pdf [2] https://archive.org/details/bitsavers_attunix7thersManualSeventhEditionVol21983_34117955 [3] There are exceptional circumstances, like overcoming problems that AT&T troff and man(7) lacked mechanisms for solving, or providing "fallbacks" for pic(1) or eqn(1) input. And I use `br` and `ne` requests in groff's man pages for "stranded line management", a problem that affects only paginated documents--that's a problem mandoc(1) is explicitly designed not to ever deal with. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 16:44 ` G. Branden Robinson @ 2026-08-23 19:30 ` Alejandro Colomar 2026-08-23 20:40 ` G. Branden Robinson ` (2 more replies) 0 siblings, 3 replies; 41+ messages in thread From: Alejandro Colomar @ 2026-08-23 19:30 UTC (permalink / raw) To: G. Branden Robinson; +Cc: linux-man, groff [-- Attachment #1: Type: text/plain, Size: 12649 bytes --] Hi Branden, > Date: 2026-08-23 11:44:51-0500 > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > [looping in groff list because Alex brought to my attention an item of > work on the new man(7) `LS` and `LE` macros that needs to be done] > > Hi Alex, > > At 2026-08-23T17:06:16+0200, Alejandro Colomar wrote: > > > Date: 2026-08-23 09:16:22-0500 > > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > > At 2026-08-23T15:55:29+0200, Alejandro Colomar wrote: > > > > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > > > > > Do you know what's wrong? > > > > > More or less. It turns out to be damned hard to balance the > > > > > requirements of (1) Automake maintainer mode; (2) building from > > > > > Git repository checkouts; and (3) building from distribution > > > > > archives. Bruno Haible has been helpful in finding scenarios > > > > > that don't work. > > > > > > > > > > https://lists.gnu.org/archive/html/groff/2026-08/msg00039.html > > > > > > > > Hmmmm, now it rings a bell. bootstrap said something about > > > > configure with maintainer mode, but I ignored that, since I had > > > > never used maintainer mode. > > > > > > Right. I introduced that very recently during the RCs for 1.25.0, > > > because it seemed necessary. But as shown, Bruno has proposed > > > patches ripping it back out. > > > > > > I'm pretty frustrated with Automake's lack of explicit support for > > > building from Git working copies. Or maybe it's brilliantly > > > documented somewhere I haven't seen yet... > > > > I dislike autotools for that and other reasons. > > Autoconf, Automake, and Libtool, the collective "autotools", are all > strongly distinguishable in purpose. I guess if you deal with them enough, you get to distinguish them. In shadow-utils, where we have an autotools-based build system, I consistently avoid to learn it. I leave it up to the other maintainers and the distro maintainers to keep it working. I only report the issues to them. To me, it'd be easier to wipe it all and write a Makefile from scratch than learning the tools. The day I have to maintain that, I'll probably do so. But distro maintainers don't want that, and so they keep helping maintain it. > Autoconf is a brilliant idea, very > well executed. I suspect that many of its its detractors possess a > constellation of negative traits: > > 1. They're not terribly competent at writing portable shell scripts; I believe I'm quite competent writing shell scripts. :) > 2. they refuse to understand the very simple principle of operation > of the m4 macro language; and I have the 2nd negative trait, though. > 3. they refuse to believe that the variety of possible deployment > environments is as wide as it is. I acknowledge this. However, some people refuse to believe that hand-crafted makefiles can also handle quite different environments too. I believe makefiles can do that just fine. It's a matter of how much makefile code you write. In the Linux man-pages project, we have 120 kB of makefiles. $ find share/mk/ -type f | xargs wc -c GNUmakefile | tail -n1 119125 total I believe that a set of makefiles that would handle all of the targets of a project like groff wouldn't take much more than that. It might be a few hundred kB. If it's well organized, it can be maintainable. Because the makefile language is so simple, bugs are easy to spot and fix, compared to autotools (possibly automake, but I can't distinguish them enough). [...] > > I've encountered CMake. It burned me far worse than the Autotools ever > have. In my view, rather than being a toolkit with which you can manage > your project's build system to your own specifications--meaning that you > can _understand_ it--it's a gigantic, baroque DWIM engine that permits a > software project to outsource their build system engineering to CMake's > maintainers. Oh, yeah, I agree with everyone here. CMake is way worse than autotools. autotools is the least evil of the non-pure-makefile build systems. > As always with outsourcing, that'll work great--and managers will love > it--until it doesn't. > > And when it doesn't, people will stumble around, blinking and wondering > where to find the expertise they'll need. > > > For groff(1), writing a portable hand-written Makefile might be too > > hard to write. > > I saw what we had before. Bertrand Garrigues did us an unquestionable > service in porting groff to Automake back in 2013/4. > > > But for the man-pages, I love the hand-written Makefile we have. > > I, too, love sticking with pure make(1) anywhere I can. POSIX Issue 8 > make(1) really allows the tool to shine. > > I nurse a glimmer of hope that the *BSD Make people can be pressured/ > bribed/shamed into supporting pattern rules at long last, and then we'll > finally get as close to world peace as is possible. > > https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/doc/doc.am?h=1.24.1#n310 > > That's an exhibit of an extremely stupid, and extremely old, problem > that I defy any BSD partisan to defend. > > > I'm still waiting for GNU Make to make a new release, and then be able > > to get rid of the mandatory -R, but other than that, it works quite > > nicely. > > Hmm, no release since 4.4 on Halloween 2022. Yeah, they might be due. Yup, I've been pinging Paul a few times in the last years. But I gave up last year. > > Yup; I don't like using tarballs. It's much easier to just check out > > git HEAD. :) > > Yes, but the tarballs get tested in a greater diversity of environments. > While I keep git HEAD "green"--I don't "git push" unless "make > distcheck" runs successfully--that applies only to my personal > development environment. groff doesn't have a CI infrastructure. > > The build system is the thing that consistently gives us the most pain > when trying to firm up a release. So right now you are pulling on HEAD > at its most fragile, ironically. The code quality should be good, _if_ > you can get the build to completion. I'm happy to uncover those bugs; it's not a problem. [...] > > diff --git i/man/man5/tunables.conf.5 w/man/man5/tunables.conf.5 > > index 91bb6b81cb85..835c409eb074 100644 > > --- i/man/man5/tunables.conf.5 > > +++ w/man/man5/tunables.conf.5 > > @@ -89,9 +89,10 @@ .SS Filters > > Filters limit the tunables following it. > > The effects of a filter are terminated by > > any of the following: > > +.P > > +.LS itemized 1 > > .IP \[bu] 3 > > The end of the file. > > -.PD 0 > > .IP \[bu] > > The end of an included file. > > .IP \[bu] > > @@ -100,7 +101,7 @@ .SS Filters > > directive. > > .IP \[bu] > > A new (possibly empty) filter. > > -.PD > > +.LE > > .P > > The syntax is: > > .P > > > > I had to add that P paragraph so that there's a blank before the list. > > That's a bit unusual, since that would technically be an empty > > paragraph; or maybe we can consider that paragraph to be the entire > > list, but that's unusual in man(7). That said, I'm fine with that. > > > > What do you think? > > I agree that it looks a little funny; if one imagines the `LS` call as > not being there at all, it looks truly redundant, and "mandoc -T lint" > will likely complain about it. > > However, you have to remember that *roff documents are not truly > block-structured. mandoc(1) really badly wants them to be, so it > pretends that they are, and that sometimes leads it to jump through > hoops...or to arguments between groff and mandoc maintainers. ;-) > > In *roffs, paragraphing macros mean "break for paragraph here", not > "paragraph opens here". True. > So, in the foregoing, given that you _want_ inter-paragraph spacing > before you start the compact list, the "isolated" `P` makes perfect > sense. I think it would be unwise to force a compact list to not be > compact prior to its first item, because doing that would foreclose the > following sort of layout. Agree. > (But I see a complementary problem.) > > $ cat ATTIC/inline-compact-list.man > .TH foo 1 2026-08-23 "groff test suite" > .SH Name > foo \- frobnicate a bar > .SH Description > This is my man page. > There are many like it, > but this one is mine. > People should read more about > .LS itemized 1 4n > .IP \[bu] > bash > .IP \[bu] > m4 > .IP \[bu] > make > .P > .LE Why not this?: .LE .P > and learn what these tools can do for them. > > $ nroff -rLL=72n -man ATTIC/inline-compact-list.man > foo(1) General Commands Manual foo(1) > > Name > foo - frobnicate a bar > > Description > This is my man page. There are many like it, but this one is mine. > People should read more about > • bash > • m4 > • make > > and learn what these tools can do for them. > > groff test suite 2026‐08‐23 foo(1) > > So there is a post-compact list space challenge. You don't want an > "empty" `IP` call prior to the `LE`--that will cause unwanted > indentation of "and learn...". You might use compactness keywords: .LS itemized precompact You could have 'precompact', 'postcompact', 'compact', and 'noncompact' (feel free to use names that aren't so terrible). > Maybe `LE` needs to accept an argument applying post-list space (and > suppress it if the argument absent). > > And maybe `LS` needs to accept another argument applying pre-list space > (and suppress it if the argument is absent). > > I'll dig into this. I might switch those defaults around; the objective > is to have `LS` and `LE` slot into existing man(7) documents as > unobtrusively as possible. As the "NEWS" file says: > > Because these macros format no text, documents employing them risk no > damage to their content if the formatter does not support them. A > man(7) document author can choose either to transition to these > macros, to manage list "compactness" and item indentation with > existing man(7) package facilities, or to employ both approaches. > > Another governing principle is "man(7) document authors should not have > to use *roff requests".[3] > > groff_man_style(7): > > Portability > ... > In roff systems, elemental functions called requests and escape > sequences control formatting operations. A request appears on a > control line. An escape sequence starts with a backslash (\) and > can appear almost anywhere. However, use of roff requests (apart > from the empty request “.”) risks poor rendering when a page is > processed by non‐roff formatters that attempt to interpret page > sources. (Historically, this was commonly attempted for HTML > conversion.) Many of these programs don’t interpret the full roff > language (let alone extensions): they may be incapable of handling > numeric expressions, control structures, or register, string, and > macro definitions, causing a document’s contents to be omitted or > presented incomprehensibly. If your document uses formatter > requests, or escape sequences not shown below, it accepts > responsibility for restoring formatter state to what the man macro > package expects. > > So I'll see what I can figure out with those lodestars in sight. > > An idea involving only compact lists and `sp` and `ns` requests is > forming already. I think I might profitably use them in the `LS` and > `LE` macro definitions, respectively. > > The foregoing example will likely spawn an automated test. > > Thanks for putting groff pre-1.25 to the test! :-) Have a lovely night! Alex > > Regards, > Branden > > [1] https://www.irif.fr/~treinen/publi/slides/minidebconf18.pdf > [2] https://archive.org/details/bitsavers_attunix7thersManualSeventhEditionVol21983_34117955 > > [3] There are exceptional circumstances, like overcoming problems that > AT&T troff and man(7) lacked mechanisms for solving, or providing > "fallbacks" for pic(1) or eqn(1) input. And I use `br` and `ne` > requests in groff's man pages for "stranded line management", a > problem that affects only paginated documents--that's a problem > mandoc(1) is explicitly designed not to ever deal with. -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 19:30 ` Alejandro Colomar @ 2026-08-23 20:40 ` G. Branden Robinson 2026-08-23 23:11 ` Alejandro Colomar 2026-08-23 22:31 ` autotools, was: Using LS/LE Ingo Schwarze [not found] ` <8DE76435-CBDB-42D6-9E0F-9E27291560B6@icloud.com> 2 siblings, 1 reply; 41+ messages in thread From: G. Branden Robinson @ 2026-08-23 20:40 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man, groff [-- Attachment #1: Type: text/plain, Size: 11502 bytes --] Hi Alex, At 2026-08-23T21:30:53+0200, Alejandro Colomar wrote: > > Date: 2026-08-23 11:44:51-0500 > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > > > [looping in groff list because Alex brought to my attention an item > > of work on the new man(7) `LS` and `LE` macros that needs to be > > done] > > At 2026-08-23T17:06:16+0200, Alejandro Colomar wrote: > > > I dislike autotools for that and other reasons. > > > > Autoconf, Automake, and Libtool, the collective "autotools", are all > > strongly distinguishable in purpose. > > I guess if you deal with them enough, you get to distinguish them. In > shadow-utils, where we have an autotools-based build system, I > consistently avoid to learn it. I leave it up to the other > maintainers and the distro maintainers to keep it working. I only > report the issues to them. To me, it'd be easier to wipe it all and > write a Makefile from scratch than learning the tools. The day I have > to maintain that, I'll probably do so. But distro maintainers don't > want that, and so they keep helping maintain it. Sometimes success looks like that. :) > > Autoconf is a brilliant idea, very well executed. I suspect that > > many of its its detractors possess a constellation of negative > > traits: > > > > 1. They're not terribly competent at writing portable shell > > scripts; > > I believe I'm quite competent writing shell scripts. :) From what I've seen, I think you're right. :) > > > 2. they refuse to understand the very simple principle of operation > > of the m4 macro language; and > > I have the 2nd negative trait, though. Nobody has time to learn everything. But I take a dim view of refusal to learn things for bad reasons. It can be hard to judge, and for sure to know exactly what a person's reasons are, because even if they don't misrepresent those reasons to others, they might lack the self-awareness necessary to know why they don't do things. For example, when I procrastinate a task, I often find myself trying to figure out post facto why I did so, after I get around to doing it. Often, I expect that a task will be more difficult than it turns out to be. I let myself get unnecessarily daunted. But, speaking only for myself, getting the "gist" of a nearly pure macro expansion engine like m4 was extremely useful in a way that I didn't appreciate at the time, because the way I learned to think about m4 ended up helping me to understand how *roff works. *roff is a very _impure_ macro expansion engine. Lots of extra stuff piled on. :) Doug McIlroy has a lovely presentation. https://www.cs.dartmouth.edu/~doug/barem4.m4 For those who fear to read M4 even when commented, the concepts are also discussed in this Computer History Museum oral history interview. https://archive.computerhistory.org/resources/access/text/2019/11/102740539-05-01-acc.pdf > > 3. they refuse to believe that the variety of possible deployment > > environments is as wide as it is. > > I acknowledge this. However, some people refuse to believe that > hand-crafted makefiles can also handle quite different environments > too. I believe makefiles can do that just fine. It's a matter of how > much makefile code you write. I wouldn't have ventured an opinion either way; I'm confident GNU Make is up to the challenge, but less sure about POSIX Issue 8 make(1). > In the Linux man-pages project, we have 120 kB of makefiles. > > $ find share/mk/ -type f | xargs wc -c GNUmakefile | tail -n1 > 119125 total > > I believe that a set of makefiles that would handle all of the targets > of a project like groff wouldn't take much more than that. It might > be a few hundred kB. If it's well organized, it can be maintainable. I was going to venture that groff's Automake files added up to much less than that. It's less--but not "much". $ wc -c $(find -name "*.am" | grep -v gnulib | sort) 31886 ./Makefile.am 1245 ./arch/mingw/mingw.am 1295 ./arch/misc/misc.am 3554 ./contrib/chem/chem.am 1324 ./contrib/eqn2graph/eqn2graph.am 2247 ./contrib/gdiffmk/gdiffmk.am 2400 ./contrib/glilypond/glilypond.am 1583 ./contrib/gperl/gperl.am 1842 ./contrib/gpinyin/gpinyin.am 1331 ./contrib/grap2graph/grap2graph.am 4559 ./contrib/hdtbl/hdtbl.am 1046 ./contrib/install-font/install-font.am 6150 ./contrib/mm/mm.am 5966 ./contrib/mom/mom.am 1312 ./contrib/pic2graph/pic2graph.am 1281 ./contrib/rfc1345/rfc1345.am 2646 ./contrib/sboxes/sboxes.am 31579 ./doc/doc.am 2210 ./font/devX100-12/devX100-12.am 2089 ./font/devX100/devX100.am 2175 ./font/devX75-12/devX75-12.am 2056 ./font/devX75/devX75.am 1757 ./font/devascii/devascii.am 2858 ./font/devdvi/devdvi.am 2496 ./font/devhtml/devhtml.am 1781 ./font/devlatin1/devlatin1.am 1739 ./font/devlbp/devlbp.am 2956 ./font/devlj4/devlj4.am 8531 ./font/devpdf/devpdf.am 5580 ./font/devps/devps.am 2387 ./font/devutf8/devutf8.am 1047 ./font/scripts/scripts.am 1331 ./man/man.am 1290 ./src/devices/grodvi/grodvi.am 1597 ./src/devices/grohtml/grohtml.am 1357 ./src/devices/grolbp/grolbp.am 1295 ./src/devices/grolj4/grolj4.am 2232 ./src/devices/gropdf/gropdf.am 1637 ./src/devices/grops/grops.am 1589 ./src/devices/grotty/grotty.am 4372 ./src/devices/xditview/xditview.am 1508 ./src/include/include.am 1048 ./src/libs/libbib/libbib.am 987 ./src/libs/libdriver/libdriver.am 3625 ./src/libs/libgroff/libgroff.am 1150 ./src/libs/libxutil/libxutil.am 3571 ./src/preproc/eqn/eqn.am 1398 ./src/preproc/grn/grn.am 1149 ./src/preproc/html/html.am 2689 ./src/preproc/pic/pic.am 1356 ./src/preproc/preconv/preconv.am 2838 ./src/preproc/refer/refer.am 1317 ./src/preproc/soelim/soelim.am 2785 ./src/preproc/tbl/tbl.am 9555 ./src/roff/groff/groff.am 1528 ./src/roff/nroff/nroff.am 2112 ./src/roff/troff/troff.am 1227 ./src/utils/addftinfo/addftinfo.am 1686 ./src/utils/afmtodit/afmtodit.am 1758 ./src/utils/grog/grog.am 1033 ./src/utils/hpftodit/hpftodit.am 2085 ./src/utils/indxbib/indxbib.am 1109 ./src/utils/lkbib/lkbib.am 1098 ./src/utils/lookbib/lookbib.am 1443 ./src/utils/pdfmom/pdfmom.am 1200 ./src/utils/pfbtops/pfbtops.am 1027 ./src/utils/tfmtodit/tfmtodit.am 1468 ./src/utils/xtotroff/xtotroff.am 15018 ./tmac/tmac.am 228376 total 228kB is an order of magnitude higher than I'd have guessed. But I should have known better--from bitter experience I should have intuited that the "doc.am" beast alone defeats any such notion. That's always the most troublesome of our Automake scripts, because we use the groff that we build to produce further artifacts. It therefore functions in part as an acceptance test. > Because the makefile language is so simple, bugs are easy to spot and > fix, compared to autotools (possibly automake, but I can't distinguish > them enough). Apart from needing an awareness of Automake's special variable names, which employ a naming scheme that one tends to notice, I can almost always get by writing an Automake script using only "make(1) brain", which is one reason I've been such crap at actually _learning_ Automake. I more often have problems writing Automake scripts that will maintain portability between GNU Make and BSD Make, which is a constraint entirely of my own choosing. > Oh, yeah, I agree with everyone here. CMake is way worse than > autotools. autotools is the least evil of the non-pure-makefile build > systems. I'm curious to hear your opinion of meson/ninja. > > Hmm, no release since 4.4 on Halloween 2022. Yeah, they might be > > due. > > Yup, I've been pinging Paul a few times in the last years. But I gave > up last year. I don't begrudge Paul D. Smith a victory lap/vacation after the triumph of POSIX Issue 8 blessing so many GNU Make extensions. :) But each one justified itself more than adequately. This document remains useful. https://gist.github.com/Earnestly/29deee4f18346da6630ed1df760f1590 > > Yes, but the tarballs get tested in a greater diversity of > > environments. While I keep git HEAD "green"--I don't "git push" > > unless "make distcheck" runs successfully--that applies only to my > > personal development environment. groff doesn't have a CI > > infrastructure. > > > > The build system is the thing that consistently gives us the most > > pain when trying to firm up a release. So right now you are pulling > > on HEAD at its most fragile, ironically. The code quality should be > > good, _if_ you can get the build to completion. > > I'm happy to uncover those bugs; it's not a problem. I appreciate your patience. It's hard not to feel like every problem discovered in an RC reflects a maintainership failure on my part. Intellectually, I know that's not how collaborative software development works. Psychologically, I want everything I produce to be so perfect that it inspires envy. :) > Why not this?: > > .LE > .P Good idea! This slots right in with no changes at all to the man(7) package. All of mandoc(1)'s complaints are as expected. $ mandoc -T lint ATTIC/inline-compact-list.man mandoc: ATTIC/inline-compact-list.man:9:2: ERROR: skipping unknown macro: .LS itemized 1 4n mandoc: ATTIC/inline-compact-list.man:18:2: ERROR: skipping unknown macro: .LE mandoc: ATTIC/inline-compact-list.man:1:5: STYLE: lower case character in document title: TH foo mandoc: ATTIC/inline-compact-list.man:10:2: WARNING: skipping paragraph macro: PP empty (I expect the third of those ("STYLE") to go away when Ingo makes his next mandoc(1) release.) So that's one fewer problem I have to solve. Thanks! But I just found a different one to replace it. groff_man(7) says: ... Use IP without arguments to associate successive paragraphs with an existing list item; to these, inter‐ paragraph spacing applies even in compact lists. ...but that last clause is not working. I'll work on that. > You might use compactness keywords: > > .LS itemized precompact > > You could have 'precompact', 'postcompact', 'compact', and > 'noncompact' (feel free to use names that aren't so terrible). This might now not be necessary at all; people can simply use your idiom. `P` (and its synonyms `LP` and `PP`) always apply inter-paragraphing spacing even in compact lists. That's on purpose, because sometimes a document uses compact lists where an item requires multiple paragraphs, or interrupts the list with commentary. I like your idiom of sticking `P` after the `LS` and/or the `LE` calls as and where one wants inter-paragraph spacing before and/or after the (compact) list. I had designed the macros with that in mind, but had not thought of that simple way to express it. A list item per se starts with either: * an argumentful `IP` macro call (for itemized or enumerated lists); or * a `TP` macro call (for definition lists). To recap, I have two macro programming problems to solve for RC3. 1. Argumentless `IP` needs to apply inter-paragraph spacing even to items in compact lists. 2. `LE` needs to break the line and cancel any indentation implied by the open list even when not followed immediately by a paragraphing macro. Regards, Branden [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 20:40 ` G. Branden Robinson @ 2026-08-23 23:11 ` Alejandro Colomar 2026-08-24 1:11 ` G. Branden Robinson 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-23 23:11 UTC (permalink / raw) To: G. Branden Robinson; +Cc: linux-man, groff [-- Attachment #1: Type: text/plain, Size: 15704 bytes --] Hi Branden, > Date: 2026-08-23 15:40:51-0500 > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > [...] > > > 2. they refuse to understand the very simple principle of operation > > > of the m4 macro language; and > > > > I have the 2nd negative trait, though. > > Nobody has time to learn everything. But I take a dim view of refusal > to learn things for bad reasons. It can be hard to judge, and for sure > to know exactly what a person's reasons are, because even if they don't > misrepresent those reasons to others, they might lack the self-awareness > necessary to know why they don't do things. > > For example, when I procrastinate a task, I often find myself trying to > figure out post facto why I did so, after I get around to doing it. I believe the reason I avoid learning m4 is that I don't think I need it. So far, GNU Make has proved to be enough for me. The day I find myself writing a build system for a project, and find it impossible or impractical to do it using GNU Make, I'll give autotools a chance. But I haven't found anything yet that I can't do easily with GNU Make. I have yet to be convinced that autotools provide any benefits over GNU Make. [...] > > > 3. they refuse to believe that the variety of possible deployment > > > environments is as wide as it is. > > > > I acknowledge this. However, some people refuse to believe that > > hand-crafted makefiles can also handle quite different environments > > too. I believe makefiles can do that just fine. It's a matter of how > > much makefile code you write. > > I wouldn't have ventured an opinion either way; I'm confident GNU Make > is up to the challenge, but less sure about POSIX Issue 8 make(1). Indeed, I use only GNU Make. <https://make.mad-scientist.net/papers/rules-of-makefiles/> Paul's first of the Rules of Makefiles: 1. Use GNU make. Don’t hassle with writing portable makefiles, use a portable make instead! Once POSIX Issue 8 make(1) gets more wide spread, I might put some effort into transforming some GNU idioms into POSIX idioms, if it's easy. > > In the Linux man-pages project, we have 120 kB of makefiles. > > > > $ find share/mk/ -type f | xargs wc -c GNUmakefile | tail -n1 > > 119125 total > > > > I believe that a set of makefiles that would handle all of the targets > > of a project like groff wouldn't take much more than that. It might > > be a few hundred kB. If it's well organized, it can be maintainable. > > I was going to venture that groff's Automake files added up to much less > than that. It's less--but not "much". > > $ wc -c $(find -name "*.am" | grep -v gnulib | sort) Out of curiosity, why would you use $()? It feels simpler (less nesting) to use xargs(1). It's also more robust, since the output of $() might grow in some cases too much for a single command. $ find -name "*.am" | grep -v gnulib | sort | xargs wc -c | tail -n1 228376 total Another issue I have with find(1) is that it's so weird that I never learnt its name flags. It has so many different ones, working slightly differently, that it's just insane. grep(1) seems simpler to learn, since we already know it anyway. Necessary link: <https://doc.cat-v.org/unix/find-history>. $ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 228376 total [...] > 228376 total Interesting. The day someone complains again about my makefiles, I'll point to this data. I checked a few other projects out of curiosity: alx@devuan:~/src/shadow/shadow/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 31885 total alx@devuan:~/src/gnu/glibc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 0 alx@devuan:~/src/gnu/gcc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 1527474 total alx@devuan:~/src/gnu/coreutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 8171 ./Makefile.am alx@devuan:~/src/gnu/findutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 35765 total Does glibc not use automake? What do they use? > 228kB is an order of magnitude higher than I'd have guessed. But I > should have known better--from bitter experience I should have intuited > that the "doc.am" beast alone defeats any such notion. It's interesting that a build system of the same size as mine but based on autotools remains problematic, while mine based on GNU makefiles consistently has zero issues. And when one is reported (a few in the last years), they are trivial and addressed in minutes. Also, *all* projects I've seen using non-make build systems consistently have issues they just leave there because the problem isn't understood. The more I see about other build systems, the more I like mine. I have to admit that writing a quality build system with GNU Make isn't easy. It took me many years to research, experiment, and learn. So, the makefile code I wrote is hardly maintainable by a novice (I wonder what'll happen to it after me). But the same is true of any good build system. I think distro maintainers are scared of makefiles because the average makefile is problematic. But the same things are said of C, and I don't think C is particularly problematic as a language. It's just the average programms that are problematic, in any language. > That's always the most troublesome of our Automake scripts, because we > use the groff that we build to produce further artifacts. It therefore > functions in part as an acceptance test. > > > Because the makefile language is so simple, bugs are easy to spot and > > fix, compared to autotools (possibly automake, but I can't distinguish > > them enough). > > Apart from needing an awareness of Automake's special variable names, Yup. I have a similar problem with make(1)'s builtin variables and rules. My makefiles start with: MAKEFLAGS += --no-builtin-rules MAKEFLAGS += --no-builtin-variables MAKEFLAGS += --warn-undefined-variables That is, what you see in the makefiles is what happens. If it's not written, it doesn't happen. > which employ a naming scheme that one tends to notice, I can almost > always get by writing an Automake script using only "make(1) brain", > which is one reason I've been such crap at actually _learning_ Automake. > > I more often have problems writing Automake scripts that will maintain > portability between GNU Make and BSD Make, which is a constraint > entirely of my own choosing. Indeed. I don't know why you self-inflict such pain. The BSDs are okay using GNU Make to build GNU-Make-based projects (IIRC, that's what Ingo told me). > > Oh, yeah, I agree with everyone here. CMake is way worse than > > autotools. autotools is the least evil of the non-pure-makefile build > > systems. > > I'm curious to hear your opinion of meson/ninja. Ninja ~~~~~ I only ever used Ninja as a generated language in projects that generate it from CMake. I've never written Ninja myself. But from what I've read, it's meant to be a generated language, so it's uninteresting to me. According to <https://stackoverflow.com/q/62847359/6872717>, Ninja seems to be faster because the configure step is slower, and focuses on generating optimized Ninja files. That's ironic, because build systems with a 'configure' pre-step are so brittle that I never trust them, and thus I end up often wiping the entire generated files, and configuring again. So, a make(1)-only build system --like mine-- would be faster. About the language itself, it seems to be a cut down version of make(1), so I couldn't do any serious work with it. It's meant to be generated- only. Meson ~~~~~ I've never used it. I also don't see why I would. It's meant to be fast, but many other systems (like Ninja) have also claimed to be fast. They (at least Ninja) actually result in being slower, as said above, so I'd have to be convinced that it's not an empty claim in the case of Meson too. To me, GNU Make seems to be really fast. As long as one writes the rules correctly (so that it can be parallelized as much as possible), it's super fast. Maybe they compare it to makefiles written by incompetent programmers, but that's not a fair claim. To be convinced, one would have to show that Meson is faster than *my* build system. But I don't believe that's possible; I don't even conceive the possibility that make(1) would be anyhow a bottle-neck there. It claims to be very readable, but everybody claims that of their languages. I find GNU Make to be the most readable build-system language, just like I find C to be the most readable programming language. FWIW, I've googled for an arbitrary example of a Meson file, and I didn't found it magically readable. So, what's the point of Meson? I guess it's okay-ish for people who are incompetent at writing build systems and just want their build system to work, like in companies, where the money is spent on programmers writing code, and not in programmers dedicated to the build system. That place was once fulfilled by CMake, and without having used Meson myself, I feel it's more or less the same (simpler than CMake, and thus better, but not by much). > > > Hmm, no release since 4.4 on Halloween 2022. Yeah, they might be > > > due. > > > > Yup, I've been pinging Paul a few times in the last years. But I gave > > up last year. > > I don't begrudge Paul D. Smith a victory lap/vacation after the triumph > of POSIX Issue 8 blessing so many GNU Make extensions. :) > > But each one justified itself more than adequately. Agree; he's doing a great work. > This document remains useful. > > https://gist.github.com/Earnestly/29deee4f18346da6630ed1df760f1590 Thanks! > > > Yes, but the tarballs get tested in a greater diversity of > > > environments. While I keep git HEAD "green"--I don't "git push" > > > unless "make distcheck" runs successfully--that applies only to my > > > personal development environment. groff doesn't have a CI > > > infrastructure. > > > > > > The build system is the thing that consistently gives us the most > > > pain when trying to firm up a release. So right now you are pulling > > > on HEAD at its most fragile, ironically. The code quality should be > > > good, _if_ you can get the build to completion. > > > > I'm happy to uncover those bugs; it's not a problem. > > I appreciate your patience. It's hard not to feel like every problem > discovered in an RC reflects a maintainership failure on my part. > > Intellectually, I know that's not how collaborative software development > works. Psychologically, I want everything I produce to be so perfect > that it inspires envy. :) But perfection takes a process. Making imperfect stuff is part of it. In some sense, that's why I avoid authoring permanent documents, like articles, or talks, with my knowledge, because I know it's far from being perfect. But I'm quite happy writing crappy documents that are part of a git repo, because I take them as a draft of the future perfection. :-) > > Why not this?: > > > > .LE > > .P > > Good idea! This slots right in with no changes at all to the man(7) > package. All of mandoc(1)'s complaints are as expected. :-) > > $ mandoc -T lint ATTIC/inline-compact-list.man > mandoc: ATTIC/inline-compact-list.man:9:2: ERROR: skipping unknown macro: .LS itemized 1 4n > mandoc: ATTIC/inline-compact-list.man:18:2: ERROR: skipping unknown macro: .LE > mandoc: ATTIC/inline-compact-list.man:1:5: STYLE: lower case character in document title: TH foo > mandoc: ATTIC/inline-compact-list.man:10:2: WARNING: skipping paragraph macro: PP empty > > (I expect the third of those ("STYLE") to go away when Ingo makes his > next mandoc(1) release.) > > So that's one fewer problem I have to solve. Thanks! You're welcome! :-) > But I just found a different one to replace it. groff_man(7) says: > > ... Use IP without arguments to associate successive > paragraphs with an existing list item; to these, inter‐ > paragraph spacing applies even in compact lists. > > ...but that last clause is not working. I'll work on that. > > > You might use compactness keywords: > > > > .LS itemized precompact > > > > You could have 'precompact', 'postcompact', 'compact', and > > 'noncompact' (feel free to use names that aren't so terrible). > > This might now not be necessary at all; people can simply use your > idiom. Yup; I wasn't really understanding why it would be necessary, but just in case I was missing something, I mentioned that possibility. I think the current feature is just fine, and moving/removing P's around, one can do the right thing. > `P` (and its synonyms `LP` and `PP`) always apply > inter-paragraphing spacing even in compact lists. That's on purpose, > because sometimes a document uses compact lists where an item requires > multiple paragraphs, or interrupts the list with commentary. > > I like your idiom of sticking `P` after the `LS` and/or the `LE` calls You problably mean before the LS and after the LE? > as and where one wants inter-paragraph spacing before and/or after the > (compact) list. I had designed the macros with that in mind, but had > not thought of that simple way to express it. Here I've written some test page. I can't handle some cases: alx@devuan:~/tmp$ cat ls.man .TH a s d f .SH test compact but separated: .P .LS itemized 1 .IP \[bu] 3 foo .IP \[bu] foo .LE .P compact, and no space before: .LS itemized 1 .IP \[bu] 3 bar .IP \[bu] bar .LE .P compact, and no space after: // How to do this?? .P .LS itemized 1 .IP \[bu] 3 baz .IP \[bu] baz .P .LE compact, and no spaces before nor after: // Same problem. .LS itemized 1 .IP \[bu] 3 qwe .IP \[bu] qwe .P .LE expanded: .LS itemized .IP \[bu] 3 qwe .IP \[bu] qwe .LE .P end of file alx@devuan:~/tmp$ /opt/local/gnu/groff/20260823_master/bin/groff -man -Tutf8 ls.man a(s) a(s) test compact but separated: • foo • foo compact, and no space before: • bar • bar compact, and no space after: // How to do this?? • baz • baz compact, and no spaces before nor after: // Same problem. • qwe • qwe expanded: • qwe • qwe end of file f d a(s) So, I expect you'll change 'P' to not add that blank line if it's within LS/LE? Or how should we write these? Cheers, Alex > > A list item per se starts with either: > > * an argumentful `IP` macro call (for itemized or enumerated lists); or > * a `TP` macro call (for definition lists). > > To recap, I have two macro programming problems to solve for RC3. > > 1. Argumentless `IP` needs to apply inter-paragraph spacing even to > items in compact lists. > > 2. `LE` needs to break the line and cancel any indentation implied by > the open list even when not followed immediately by a paragraphing > macro. > > Regards, > Branden -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-23 23:11 ` Alejandro Colomar @ 2026-08-24 1:11 ` G. Branden Robinson 2026-08-24 2:01 ` Using LS/LE Collin Funk 2026-08-24 11:00 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar 0 siblings, 2 replies; 41+ messages in thread From: G. Branden Robinson @ 2026-08-24 1:11 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man, groff [-- Attachment #1.1: Type: text/plain, Size: 18990 bytes --] Hi Alex, At 2026-08-24T01:11:00+0200, Alejandro Colomar wrote: > I believe the reason I avoid learning m4 is that I don't think I need > it. So far, GNU Make has proved to be enough for me. The day I find > myself writing a build system for a project, and find it impossible or > impractical to do it using GNU Make, I'll give autotools a chance. > But I haven't found anything yet that I can't do easily with GNU Make. > > I have yet to be convinced that autotools provide any benefits over > GNU Make. For me, the biggest benefit of GNU Automake is the test harness that's just lying there. It's stupidly easy to add a new test script.[0] I would not have had the courage to undertake serious groff development if I could not build a scaffold that gives me a fighting chance to keep the impact of my changes under control and predictable. As with any system where a test suite is retrofitted on, we're always finding new things that need tests. But with over 370 test scripts now, some of which perform many different individualized "checks",[1] I think we can claim growing confidence in groff's determinism. [I wrote:] > > I wouldn't have ventured an opinion either way; I'm confident GNU > > Make is up to the challenge, but less sure about POSIX Issue 8 > > make(1). > > Indeed, I use only GNU Make. > > <https://make.mad-scientist.net/papers/rules-of-makefiles/> > > Paul's first of the Rules of Makefiles: > > 1. Use GNU make. > > Don’t hassle with writing portable makefiles, use a portable > make instead! > > Once POSIX Issue 8 make(1) gets more wide spread, I might put some > effort into transforming some GNU idioms into POSIX idioms, if it's > easy. Should be. The only change I can think of off the top of my head is that you'll need to covert FOO:=bar to FOO::=bar ...because BSD implemented `:=` with different semantics. Less useful ones, but they planted their feet. `:=` is therefore ambiguous. (If one wants BSD `:=` semantics, one uses the truly ghastly `:::=`. Serves 'em right! 3;-) ) > > $ wc -c $(find -name "*.am" | grep -v gnulib | sort) > > Out of curiosity, why would you use $()? It feels simpler (less > nesting) to use xargs(1). It's also more robust, since the output of > $() might grow in some cases too much for a single command. I seldom (if ever) encounter the final difficulty. When working interactively at the command line, I'm practically never trying to hunt up things across an entire file system. Just $HOME is too big to be wieldy. If I really have to trawl my gigantic $HOME, I write a script and go do something else for a while. > $ find -name "*.am" | grep -v gnulib | sort | xargs wc -c | tail -n1 > 228376 total You can see that my "phrasing" is shorter. Nice for interactive use. For non-ephemeral artifacts, I prefer more "readable" syntax, by which I mean ones easier to speak aloud in English, because one might be discussing the content with colleagues. > Another issue I have with find(1) is that it's so weird that I never > learnt its name flags. That it is. > It has so many different ones, working slightly differently, that it's > just insane. Sometimes, it's what you need. I learned find/xargs on Solaris, which was much leaner than GNU findutils--but the weirdness was already baked in. As I understand it, find(1) and xargs(1) didn't come out of the Bell Labs CSRC, but rather the USG, the folks who did PWB/Unix and then ultimately System III and System V. They also came up with cpio(1). Their brains worked differently than the research folks'. > grep(1) seems simpler to learn, > since we already know it anyway. > Necessary link: <https://doc.cat-v.org/unix/find-history>. Oh, hah. Yes. I'll ask you to take my word for it that I wrote my historical summary above before reading this part of your message. ;-) > > 228376 total A substantial amount of this is the GNU GPLv3 notice boilerplate. ...but I'm not arsing myself to measure it. > Interesting. The day someone complains again about my makefiles, I'll > point to this data. I checked a few other projects out of curiosity: > > alx@devuan:~/src/shadow/shadow/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > 31885 total > alx@devuan:~/src/gnu/glibc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > 0 > alx@devuan:~/src/gnu/gcc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > 1527474 total > alx@devuan:~/src/gnu/coreutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > 8171 ./Makefile.am > alx@devuan:~/src/gnu/findutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > 35765 total > > Does glibc not use automake? What do they use? Hand-written Makefiles, apparently! For a while I followed their Git commits, but I'm well behind on them. glibc and GCC saturated my ability to keep up with the projects I track. > > 228kB is an order of magnitude higher than I'd have guessed. But I > > should have known better--from bitter experience I should have > > intuited that the "doc.am" beast alone defeats any such notion. > > It's interesting that a build system of the same size as mine but > based on autotools remains problematic, while mine based on GNU > makefiles consistently has zero issues. And when one is reported (a > few in the last years), they are trivial and addressed in minutes. > Also, *all* projects I've seen using non-make build systems > consistently have issues they just leave there because the problem > isn't understood. The more I see about other build systems, the more > I like mine. groff may be trying to solve somewhat different problems. We have weird-ass problems like this: https://savannah.gnu.org/bugs/?68567 ...and I daresay you don't. 'Course, that was an Autoconf problem, not an Automake problem. But it was still a build dependency issue, and thus ultimately had impact on Makefiles. > I have to admit that writing a quality build system with GNU Make > isn't easy. It took me many years to research, experiment, and learn. > So, the makefile code I wrote is hardly maintainable by a novice (I > wonder what'll happen to it after me). But the same is true of any > good build system. Yeah. Not long after I took a job in Sydney, I was gifted with a printed-out meme as decoration for my cubicle wall. Attached. CMake and Australian culture taught me how to swear as if I were myself a member of Insane Clown Posse. :-| > I think distro maintainers are scared of makefiles because the average > makefile is problematic. But the same things are said of C, and I > don't think C is particularly problematic as a language. Disagree with you here. C and C++ are _terrible_ languages. :D (By multiple important metrics, English is a terrible natural language. Its phonemic inventory is unusually large and its spelling thoroughly unpredictable. It is about as hard for non-native speakers to acquire as Arabic, Russian, or Mandarin or Cantonese Chinese are to monoglot English speakers. I happen to love the English language. But I acknowledge that it is a cruel mistress.) If I ever get over the fence to the greener grass of Ada, I'll let you know how I find it. ;-) > It's just the average programms that are problematic, in any language. Average programmers do average work in any language. The parameter over which language designers have control is whether the work gets "done" at all. What "done" _means_ is back in the hands of the programmer again. > Yup. I have a similar problem with make(1)'s builtin variables and > rules. My makefiles start with: > > MAKEFLAGS += --no-builtin-rules > MAKEFLAGS += --no-builtin-variables > MAKEFLAGS += --warn-undefined-variables > > That is, what you see in the makefiles is what happens. If it's not > written, it doesn't happen. This looks like a good idea. > > I more often have problems writing Automake scripts that will > > maintain portability between GNU Make and BSD Make, which is a > > constraint entirely of my own choosing. > > Indeed. I don't know why you self-inflict such pain. The BSDs are > okay using GNU Make to build GNU-Make-based projects (IIRC, that's > what Ingo told me). groff already had that trait. It's not something I had to make happen. Given that, I'm loath to give it up. Also, it's much more satisfying to complain about BSD make as someone who _uses_ and maintains a project that supports building with it. That way, when BSD Make partisans ignore my complaints, as they always have to date,[2] it's clear that they're ignoring a real user of their tool rather than some fruit loop on Phoronix who has lots of opinions but doesn't even write software. > Ninja > ~~~~~ > > I only ever used Ninja as a generated language in projects that > generate it from CMake. I've never written Ninja myself. But from > what I've read, it's meant to be a generated language, so it's > uninteresting to me. Right. My understanding is that Meson is usually the thing that generates it. > So, what's the point of Meson? I guess it's okay-ish for people who > are incompetent at writing build systems and just want their build > system to work, like in companies, where the money is spent on > programmers writing code, and not in programmers dedicated to the > build system. That place was once fulfilled by CMake, and without > having used Meson myself, I feel it's more or less the same (simpler > than CMake, and thus better, but not by much). Well, Meson apparently arose in the ferment of tech sector rage and resentment against GNU GPLv3...a rage carefully calculated to ease the extraction of economic rents and the exploitation of engineers' labor. It's not under a copyleft license. (It uses Apache 2.0.) Meson's author perceived a market opportunity and seized it. Good for him. He seems to run a highly active podcast, so maybe he's living his best life! Wouldn't surprise me at all if the tradeoffs in adopting Meson are much tougher decisions than its partisans credit, nor that its best features are isomorphic to properties GNU Make (or even CMake) already has. It is very frequently the case that technologies get adopted for reasons other than their suitability to the task. Just look at the x86 ISA. How on earth did _that_ become dominant, relative to its competitors from 1978 to 1995? The situation is similar to that captured by an old saying, "you can't reason a man out of a position he wasn't reasoned into". If an engineer selects, or is directed to select, a tool because "it's not copyleft", no demonstration of a copylefted alternative tool's superiority will succeed. Even if its replacement with a copylefted tool would materially affect the department's profitability, resistance will be found, and if the case gets too dramatic to resist, then when the change is eventually made, the change in the department's fortunes will be attributed wholly to other factors, most likely a VP or Director's "amazing leadership", without substance or explanation. To make sense of decision making in most software engineering firms, it helps to understand corporate America (and much of Europe). Copyleft is Communism and must be opposed with jihadist fervor. Say what you will about the hijackers who knocked down the World Trade Towers, they had no truck with Marxism-Leninism. They were always steadfast on that point. How do you think they got where they did?[3][4] (I have problems with Marx and Lenin myself, but no one ever asks what they are. ;-) ) > > I appreciate your patience. It's hard not to feel like every > > problem discovered in an RC reflects a maintainership failure on my > > part. > > > > Intellectually, I know that's not how collaborative software > > development works. Psychologically, I want everything I produce to > > be so perfect that it inspires envy. :) > > But perfection takes a process. Making imperfect stuff is part of it. > In some sense, that's why I avoid authoring permanent documents, like > articles, or talks, with my knowledge, because I know it's far from > being perfect. But I'm quite happy writing crappy documents that are > part of a git repo, because I take them as a draft of the future > perfection. :-) Yup. Intellectually, I get it. And feedback from folks like Bruno is an important part of the quality assurance process. I'm happy that it produces actionable items. > > But I just found a different one to replace it. groff_man(7) says: > > > > ... Use IP without arguments to associate successive > > paragraphs with an existing list item; to these, inter‐ > > paragraph spacing applies even in compact lists. > > > > ...but that last clause is not working. I'll work on that. > > > > > You might use compactness keywords: > > > > > > .LS itemized precompact > > > > > > You could have 'precompact', 'postcompact', 'compact', and > > > 'noncompact' (feel free to use names that aren't so terrible). > > > > This might now not be necessary at all; people can simply use your > > idiom. > > Yup; I wasn't really understanding why it would be necessary, but just > in case I was missing something, I mentioned that possibility. I > think the current feature is just fine, and moving/removing P's > around, one can do the right thing. > > > `P` (and its synonyms `LP` and `PP`) always apply inter-paragraphing > > spacing even in compact lists. That's on purpose, because sometimes > > a document uses compact lists where an item requires multiple > > paragraphs, or interrupts the list with commentary. > > > > I like your idiom of sticking `P` after the `LS` and/or the `LE` > > calls > > You problably mean before the LS and after the LE? Actually either way works, right now. I don't plan to change that. $ cat ATTIC/inline-compact-list.man .TH foo 1 2026-08-23 "groff test suite" .SH Name foo \- frobnicate a bar .SH Description This is my man page. There are many like it, but this one is mine. .SS "Example 1" People should read more about .P .LS itemized 1 4n .IP \[bu] bash .IP This line should be preceded by vertical space. .IP \[bu] m4 .IP \[bu] make .LE .P and learn what these tools can do for them. .SS "Example 2" (This example should look the same as the first.) People should read more about .LS itemized 1 4n .P .IP \[bu] bash .IP This line should be preceded by vertical space. .IP \[bu] m4 .IP \[bu] make .LE .P and learn what these tools can do for them. $ ./build/test-groff -rLL=72n -man -T utf8 ATTIC/inline-compact-list.man foo(1) General Commands Manual foo(1) Name foo - frobnicate a bar Description This is my man page. There are many like it, but this one is mine. Example 1 People should read more about • bash This line should be preceded by vertical space. • m4 • make and learn what these tools can do for them. Example 2 (This example should look the same as the first.) People should read more about • bash This line should be preceded by vertical space. • m4 • make and learn what these tools can do for them. groff test suite 2026‐08‐23 foo(1) > > as and where one wants inter-paragraph spacing before and/or after > > the (compact) list. I had designed the macros with that in mind, > > but had not thought of that simple way to express it. > > Here I've written some test page. I can't handle some cases: > > alx@devuan:~/tmp$ cat ls.man > .TH a s d f > .SH test > compact but separated: > .P > .LS itemized 1 > .IP \[bu] 3 > foo > .IP \[bu] > foo > .LE > .P > compact, and no space before: > .LS itemized 1 > .IP \[bu] 3 > bar > .IP \[bu] > bar > .LE > .P > compact, and no space after: // How to do this?? > .P > .LS itemized 1 > .IP \[bu] 3 > baz > .IP \[bu] > baz > .P > .LE > compact, and no spaces before nor after: // Same problem. > .LS itemized 1 > .IP \[bu] 3 > qwe > .IP \[bu] > qwe > .P > .LE > expanded: > .LS itemized > .IP \[bu] 3 > qwe > .IP \[bu] > qwe > .LE > .P > end of file > alx@devuan:~/tmp$ /opt/local/gnu/groff/20260823_master/bin/groff -man -Tutf8 ls.man > a(s) a(s) > > test > compact but separated: > > • foo > • foo > > compact, and no space before: > • bar > • bar > > compact, and no space after: // How to do this?? > > • baz > • baz > > compact, and no spaces before nor after: // Same problem. > • qwe > • qwe > > expanded: > > • qwe > > • qwe > > end of file > > f d a(s) Yup, that looks like the problem I flagged as #2 earlier. > > 2. `LE` needs to break the line and cancel any indentation implied > > by the open list even when not followed immediately by a > > paragraphing macro. > So, I expect you'll change 'P' to not add that blank line if it's > within LS/LE? Or how should we write these? No, I _want_ `P` to add a blank line, before and internally to a list, even a compact one. But I want `LE` to be able to configurably _suppress_ a blank line after a compact list. Right now the simplest thing to do seems like giving it a Boolean argument to eat. Right now I'm conceptualizing that argument as "post-compactness", because that way it's likely to be consistent with any specified "compactness" Boolean argument to `LS`, but I wouldn't count on the former term surviving to code or documentation. Regards, Branden [0] Example: https://cgit.git.savannah.gnu.org/cgit/groff.git/commit/?id=aa43b5e261a7b4fe3b09e6673f145b0e123faffa [1] Of which this one is probably the most savage: https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/src/roff/groff/tests/check-delimiter-validity.sh?h=1.24.1 [2] With one honorable exception, a *BSD luminary who contacted me privately. Haven't heard back from him in over a year now, but these things can take time. [3] https://openlibrary.org/works/OL193645W/The_Looming_Tower [4] https://www.c-span.org/program/american-history-tv/charlie-wilsons-war/123837 [-- Attachment #1.2: icp_build_systems_how_do_they_work.jpeg --] [-- Type: image/jpeg, Size: 72947 bytes --] [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE 2026-08-24 1:11 ` G. Branden Robinson @ 2026-08-24 2:01 ` Collin Funk 2026-08-24 11:08 ` Alejandro Colomar 2026-08-24 11:00 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar 1 sibling, 1 reply; 41+ messages in thread From: Collin Funk @ 2026-08-24 2:01 UTC (permalink / raw) To: G. Branden Robinson; +Cc: Alejandro Colomar, linux-man, groff "G. Branden Robinson" <g.branden.robinson@gmail.com> writes: >> Interesting. The day someone complains again about my makefiles, I'll >> point to this data. I checked a few other projects out of curiosity: >> >> alx@devuan:~/src/shadow/shadow/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 >> 31885 total >> alx@devuan:~/src/gnu/glibc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 >> 0 >> alx@devuan:~/src/gnu/gcc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 >> 1527474 total >> alx@devuan:~/src/gnu/coreutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 >> 8171 ./Makefile.am >> alx@devuan:~/src/gnu/findutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 >> 35765 total >> >> Does glibc not use automake? What do they use? > > Hand-written Makefiles, apparently! For a while I followed their Git > commits, but I'm well behind on them. glibc and GCC saturated my > ability to keep up with the projects I track. Yes, glibc uses GNU make extensively. It is quite difficult to read if you do not understand GNU make extensions, compared to Automake which is for the most part just declaring targets and sources. It also requires more upkeep to make sure things work correctly, e.g., parallelism. So, I don't think pointing out that Automake files have a similar file size to regular Makefiles is a good comparison. Collin ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE 2026-08-24 2:01 ` Using LS/LE Collin Funk @ 2026-08-24 11:08 ` Alejandro Colomar 0 siblings, 0 replies; 41+ messages in thread From: Alejandro Colomar @ 2026-08-24 11:08 UTC (permalink / raw) To: Collin Funk; +Cc: G. Branden Robinson, linux-man, groff [-- Attachment #1: Type: text/plain, Size: 3100 bytes --] Hi Collin, > Date: 2026-08-23 19:01:06-0700 > From: Collin Funk <collin.funk1@gmail.com> > > "G. Branden Robinson" <g.branden.robinson@gmail.com> writes: > > >> Interesting. The day someone complains again about my makefiles, I'll > >> point to this data. I checked a few other projects out of curiosity: > >> > >> alx@devuan:~/src/shadow/shadow/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > >> 31885 total > >> alx@devuan:~/src/gnu/glibc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > >> 0 > >> alx@devuan:~/src/gnu/gcc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > >> 1527474 total > >> alx@devuan:~/src/gnu/coreutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > >> 8171 ./Makefile.am > >> alx@devuan:~/src/gnu/findutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > >> 35765 total > >> > >> Does glibc not use automake? What do they use? > > > > Hand-written Makefiles, apparently! For a while I followed their Git > > commits, but I'm well behind on them. glibc and GCC saturated my > > ability to keep up with the projects I track. > > Yes, glibc uses GNU make extensively. It is quite difficult to read if > you do not understand GNU make extensions, compared to Automake which is > for the most part just declaring targets and sources. 'for the most part' of the text written. Then you have to understand everything that isn't written, which is more difficult than grepping in the GNU Make manual for a few extensions. You don't know '?:=' in GNU Make, then grep for '?:=' in the GNU Make manual. Simple. You don't know why/how Automake is doing something? Good luck guessing why. > It also requires > more upkeep to make sure things work correctly, e.g., parallelism. This is not true. The shadow-utils project (which uses autotools) has bugs open for years because `make dist -j4` doesn't work (and it hasn't been fixed yet). The Linux man-pages build system works fine with -j128. Ignoring the initial cost in writing the build system, maintenance is quite cheap. And if a bug ever shows up in the GNU Make code, I'm confident it'll take a few minutes to debug it and fix it. The parallelism problem in makefiles comes from incorrect use of makefiles. That is, use of recursive make(1). But recursive make(1) is discouraged. If you have a single make(1) process controlling everything, it runs smoothly. > So, I don't think pointing out that Automake files have a similar file > size to regular Makefiles is a good comparison. Given the same size, Automake is less readable, because it has more implicit assumptions. In GNU Make, there are very few assumptions, and I bring that to zero by disabling the builtins. If you can't read the grammar, it's a matter of reading the documentation. GNU Make has pretty good documentation. Have a lovely day! Alex > > Collin -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-24 1:11 ` G. Branden Robinson 2026-08-24 2:01 ` Using LS/LE Collin Funk @ 2026-08-24 11:00 ` Alejandro Colomar 1 sibling, 0 replies; 41+ messages in thread From: Alejandro Colomar @ 2026-08-24 11:00 UTC (permalink / raw) To: G. Branden Robinson; +Cc: linux-man, groff [-- Attachment #1: Type: text/plain, Size: 15248 bytes --] Hi Branden, > Date: 2026-08-23 20:11:29-0500 > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > Hi Alex, > > At 2026-08-24T01:11:00+0200, Alejandro Colomar wrote: > > I believe the reason I avoid learning m4 is that I don't think I need > > it. So far, GNU Make has proved to be enough for me. The day I find > > myself writing a build system for a project, and find it impossible or > > impractical to do it using GNU Make, I'll give autotools a chance. > > But I haven't found anything yet that I can't do easily with GNU Make. > > > > I have yet to be convinced that autotools provide any benefits over > > GNU Make. > > For me, the biggest benefit of GNU Automake is the test harness that's > just lying there. It's stupidly easy to add a new test script.[0] > > [0] Example: > > https://cgit.git.savannah.gnu.org/cgit/groff.git/commit/?id=aa43b5e261a7b4fe3b09e6673f145b0e123faffa The marginal cost of adding one test is small (but nonzero), but is that also true for the first test? FWIW, I used the build system of the man-pages for a C library project, and while I obviously had to add some makefile code for adding tests, the marginal cost of adding one test file is zero. That is, the makefiles find anything under share/tests/, and include it to the file list. [...] > [I wrote:] > > > I wouldn't have ventured an opinion either way; I'm confident GNU > > > Make is up to the challenge, but less sure about POSIX Issue 8 > > > make(1). > > > > Indeed, I use only GNU Make. > > > > <https://make.mad-scientist.net/papers/rules-of-makefiles/> > > > > Paul's first of the Rules of Makefiles: > > > > 1. Use GNU make. > > > > Don’t hassle with writing portable makefiles, use a portable > > make instead! > > > > Once POSIX Issue 8 make(1) gets more wide spread, I might put some > > effort into transforming some GNU idioms into POSIX idioms, if it's > > easy. > > Should be. The only change I can think of off the top of my head is > that you'll need to covert > > FOO:=bar > > to > > FOO::=bar > > ...because BSD implemented `:=` with different semantics. Less useful > ones, but they planted their feet. > > `:=` is therefore ambiguous. (If one wants BSD `:=` semantics, one uses > the truly ghastly `:::=`. Serves 'em right! 3;-) ) Thanks! I've applied the following commit. commit af165bbd04c6f85c66a33452b1d247f32c926ae6 Author: Alejandro Colomar <alx@kernel.org> Date: 2026-08-24 12:12:11 +0200 share/mk/, GNUmakefile: Use ::= instead of := That's what POSIX.1-2024 standardized. Suggested-by: "G. Branden Robinson" <g.branden.robinson@gmail.com> Message-ID: <20260824011129.njsipdzmay4smp6i@illithid> Signed-off-by: Alejandro Colomar <alx@kernel.org> diff --git a/GNUmakefile b/GNUmakefile index 3f2ea50baa66..f8b3add5b325 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -2,8 +2,8 @@ # SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception -SHELL := bash -.SHELLFLAGS := -Eeuo pipefail -c +SHELL ::= bash +.SHELLFLAGS ::= -Eeuo pipefail -c ifneq (4.4.999,$(firstword $(sort 4.4.999 $(MAKE_VERSION)))) [...] > > > $ wc -c $(find -name "*.am" | grep -v gnulib | sort) > > > > Out of curiosity, why would you use $()? It feels simpler (less > > nesting) to use xargs(1). It's also more robust, since the output of > > $() might grow in some cases too much for a single command. > > I seldom (if ever) encounter the final difficulty. When working > interactively at the command line, I'm practically never trying to hunt > up things across an entire file system. Just $HOME is too big to be > wieldy. If I really have to trawl my gigantic $HOME, I write a script > and go do something else for a while. > > > $ find -name "*.am" | grep -v gnulib | sort | xargs wc -c | tail -n1 > > 228376 total > > You can see that my "phrasing" is shorter. Nice for interactive use. $() vs |xargs is only shorter by a 3 characters. Also, $() has three characters for which you have to hold shift, vs 1 from |xargs, which makes $() actually harder to type than |xargs, IMHO. Some interesting feature of |xargs is that you can prepend it with '|tee /dev/tty' when you need to debug the input, when something goes wrong. [...] > > grep(1) seems simpler to learn, > > since we already know it anyway. > > Necessary link: <https://doc.cat-v.org/unix/find-history>. > > Oh, hah. Yes. I'll ask you to take my word for it that I wrote my > historical summary above before reading this part of your message. ;-) :-) [...] > > Interesting. The day someone complains again about my makefiles, I'll > > point to this data. I checked a few other projects out of curiosity: > > > > alx@devuan:~/src/shadow/shadow/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > > 31885 total > > alx@devuan:~/src/gnu/glibc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > > 0 > > alx@devuan:~/src/gnu/gcc/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > > 1527474 total > > alx@devuan:~/src/gnu/coreutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > > 8171 ./Makefile.am > > alx@devuan:~/src/gnu/findutils/master$ find | grep '\.am$' | grep -v gnulib | sort | xargs wc -c | tail -n1 > > 35765 total > > > > Does glibc not use automake? What do they use? > > Hand-written Makefiles, apparently! For a while I followed their Git > commits, but I'm well behind on them. glibc and GCC saturated my > ability to keep up with the projects I track. Oh, nice! > > > 228kB is an order of magnitude higher than I'd have guessed. But I > > > should have known better--from bitter experience I should have > > > intuited that the "doc.am" beast alone defeats any such notion. > > > > It's interesting that a build system of the same size as mine but > > based on autotools remains problematic, while mine based on GNU > > makefiles consistently has zero issues. And when one is reported (a > > few in the last years), they are trivial and addressed in minutes. > > Also, *all* projects I've seen using non-make build systems > > consistently have issues they just leave there because the problem > > isn't understood. The more I see about other build systems, the more > > I like mine. > > groff may be trying to solve somewhat different problems. > > We have weird-ass problems like this: > > https://savannah.gnu.org/bugs/?68567 > > ...and I daresay you don't. I _think_ had some issues that are somewhat similar in the build system of a C library. I had to deal with them in the pkg-config file. I say I think, because I don't understand that problem enough. > 'Course, that was an Autoconf problem, not an Automake problem. But it > was still a build dependency issue, and thus ultimately had impact on > Makefiles. > > > I have to admit that writing a quality build system with GNU Make > > isn't easy. It took me many years to research, experiment, and learn. > > So, the makefile code I wrote is hardly maintainable by a novice (I > > wonder what'll happen to it after me). But the same is true of any > > good build system. > > Yeah. Not long after I took a job in Sydney, I was gifted with a > printed-out meme as decoration for my cubicle wall. Attached. :D > CMake and Australian culture taught me how to swear as if I were myself > a member of Insane Clown Posse. :-| > > > I think distro maintainers are scared of makefiles because the average > > makefile is problematic. But the same things are said of C, and I > > don't think C is particularly problematic as a language. > > Disagree with you here. C and C++ are _terrible_ languages. :D It has many dialects, and I acknowledge some of them --notably including ISO C89-- are terrible. But some dialects, such as GNU C2y, are quite nice. Please don't judge the language by its worst dialects. :) > (By multiple important metrics, English is a terrible natural language. > Its phonemic inventory is unusually large and its spelling thoroughly > unpredictable. It is about as hard for non-native speakers to acquire > as Arabic, Russian, or Mandarin or Cantonese Chinese are to monoglot > English speakers. I happen to love the English language. But I > acknowledge that it is a cruel mistress.) Phonetically, Spanish might be some of the simplest languages. On the other hand, written English is quite simple compared to other languages (including Spanish). It doesn't conjugate much. I've heard Norwegian is even simpler than English when written, and possibly one of the simplest languages. I haven't learnt it, so I can't judge. > If I ever get over the fence to the greener grass of Ada, I'll let you > know how I find it. ;-) > > > It's just the average programms that are problematic, in any language. > > Average programmers do average work in any language. The parameter over > which language designers have control is whether the work gets "done" at > all. What "done" _means_ is back in the hands of the programmer again. > [...] > > > I like your idiom of sticking `P` after the `LS` and/or the `LE` > > > calls > > > > You problably mean before the LS and after the LE? > > Actually either way works, right now. I don't plan to change that. > > $ cat ATTIC/inline-compact-list.man > .TH foo 1 2026-08-23 "groff test suite" > .SH Name > foo \- frobnicate a bar > .SH Description > This is my man page. > There are many like it, > but this one is mine. > .SS "Example 1" > People should read more about > .P > .LS itemized 1 4n > .IP \[bu] > bash > .IP > This line should be preceded by vertical space. > .IP \[bu] > m4 > .IP \[bu] > make > .LE > .P > and learn what these tools can do for them. > .SS "Example 2" > (This example should look the same as the first.) > People should read more about > .LS itemized 1 4n > .P > .IP \[bu] > bash > .IP > This line should be preceded by vertical space. > .IP \[bu] > m4 > .IP \[bu] > make > .LE > .P > and learn what these tools can do for them. > $ ./build/test-groff -rLL=72n -man -T utf8 ATTIC/inline-compact-list.man > foo(1) General Commands Manual foo(1) > > Name > foo - frobnicate a bar > > Description > This is my man page. There are many like it, but this one is mine. > > Example 1 > People should read more about > > • bash > This line should be preceded by vertical space. > • m4 > • make > > and learn what these tools can do for them. > > Example 2 > (This example should look the same as the first.) People should > read more about > > • bash > This line should be preceded by vertical space. > • m4 > • make > > and learn what these tools can do for them. > > groff test suite 2026‐08‐23 foo(1) > > > > as and where one wants inter-paragraph spacing before and/or after > > > the (compact) list. I had designed the macros with that in mind, > > > but had not thought of that simple way to express it. > > > > Here I've written some test page. I can't handle some cases: > > > > alx@devuan:~/tmp$ cat ls.man > > .TH a s d f > > .SH test > > compact but separated: > > .P > > .LS itemized 1 > > .IP \[bu] 3 > > foo > > .IP \[bu] > > foo > > .LE > > .P > > compact, and no space before: > > .LS itemized 1 > > .IP \[bu] 3 > > bar > > .IP \[bu] > > bar > > .LE > > .P > > compact, and no space after: // How to do this?? > > .P > > .LS itemized 1 > > .IP \[bu] 3 > > baz > > .IP \[bu] > > baz > > .P > > .LE > > compact, and no spaces before nor after: // Same problem. > > .LS itemized 1 > > .IP \[bu] 3 > > qwe > > .IP \[bu] > > qwe > > .P > > .LE > > expanded: > > .LS itemized > > .IP \[bu] 3 > > qwe > > .IP \[bu] > > qwe > > .LE > > .P > > end of file > > alx@devuan:~/tmp$ /opt/local/gnu/groff/20260823_master/bin/groff -man -Tutf8 ls.man > > a(s) a(s) > > > > test > > compact but separated: > > > > • foo > > • foo > > > > compact, and no space before: > > • bar > > • bar > > > > compact, and no space after: // How to do this?? > > > > • baz > > • baz > > > > compact, and no spaces before nor after: // Same problem. > > • qwe > > • qwe > > > > expanded: > > > > • qwe > > > > • qwe > > > > end of file > > > > f d a(s) > > Yup, that looks like the problem I flagged as #2 earlier. > > > > 2. `LE` needs to break the line and cancel any indentation implied > > > by the open list even when not followed immediately by a > > > paragraphing macro. > > > So, I expect you'll change 'P' to not add that blank line if it's > > within LS/LE? Or how should we write these? > > No, I _want_ `P` to add a blank line, before and internally to a list, > even a compact one. But I want `LE` to be able to configurably > _suppress_ a blank line after a compact list. Right now the simplest > thing to do seems like giving it a Boolean argument to eat. > > Right now I'm conceptualizing that argument as "post-compactness", > because that way it's likely to be consistent with any specified > "compactness" Boolean argument to `LS`, but I wouldn't count on the > former term surviving to code or documentation. I think we don't need an argument. Just a behavior fix. alx@devuan:~/tmp$ cat ls.man .TH a s d f .SH test compact, and no spaces before nor after: // Same problem. .LS itemized 1 .IP \[bu] 3 qwe .IP \[bu] qwe .LE end of file alx@devuan:~/tmp$ /opt/local/gnu/groff/20260823_master/bin/groff -man -Tutf8 ls.man a(s) a(s) test compact, and no spaces before nor after: // Same problem. • qwe • qwe end of file f d a(s) I think LE should insert at least a break. With that, we'd have this solved, I think. Have a lovely day! Alex > > Regards, > Branden > > [1] Of which this one is probably the most savage: > > https://cgit.git.savannah.gnu.org/cgit/groff.git/tree/src/roff/groff/tests/check-delimiter-validity.sh?h=1.24.1 > > [2] With one honorable exception, a *BSD luminary who contacted me > privately. Haven't heard back from him in over a year now, but > these things can take time. -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* autotools, was: Using LS/LE 2026-08-23 19:30 ` Alejandro Colomar 2026-08-23 20:40 ` G. Branden Robinson @ 2026-08-23 22:31 ` Ingo Schwarze 2026-08-24 0:09 ` Alejandro Colomar 2026-08-29 4:36 ` G. Branden Robinson [not found] ` <8DE76435-CBDB-42D6-9E0F-9E27291560B6@icloud.com> 2 siblings, 2 replies; 41+ messages in thread From: Ingo Schwarze @ 2026-08-23 22:31 UTC (permalink / raw) To: Alejandro Colomar; +Cc: g.branden.robinson, linux-man, groff Hello Alejandro and Branden, Alejandro Colomar wrote on Sun, Aug 23, 2026 at 09:30:53PM +0200: > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> >> Autoconf, Automake, and Libtool, the collective "autotools", are all >> strongly distinguishable in purpose. > I guess if you deal with them enough, you get to distinguish them. > In shadow-utils, where we have an autotools-based build system, I > consistently avoid to learn it. I leave it up to the other maintainers > and the distro maintainers to keep it working. I only report the issues > to them. To me, it'd be easier to wipe it all and write a Makefile from > scratch than learning the tools. The day I have to maintain that, I'll > probably do so. As one data point for Alejandro, that's precisely what i chose to do, and not even because i had never used autoconf before, just because i considered using autoconf massive overkill and likely to cause a maintenance nightmare. The same applies to automake, but to an even higher degree. Look at this: $ pwd /co/mandoc $ wc configure # handwritten, human-readable, and portable 693 2537 20370 configure $ wc Makefile # handwritten, human-readable, and portable 619 1600 16050 Makefile $ wc config.h # generated by ./configure 54 150 1326 config.h Apart from that, there are 37 test-*.c feature test files, all handwritten and human-readable, 723 lines grand total, i.e. less than twenty lines on average. Finally, there are 19 compat_*.c portable replacement implementations for systems lacking certain functions. >> Autoconf is a brilliant idea, very >> well executed. I suspect that many of its its detractors possess a >> constellation of negative traits: >> >> 1. They're not terribly competent at writing portable shell scripts; That's indeed true for me. While i have done a fair amount of shell programming (including writing an entire incremental backup system in pure sh(1) more than two decades ago, just for the heck of learning the language and testing my skill on a non-trivial project, which was obviously a terrible idea - yet the project was in use for many years at that organization), and including some work in the OpenBSD /etc/rc system, particularly rc.d(8) and daily(8), i'm certainly not nearly as good at sh(1) as our true shell wizards like Alexander Hall or Andrew Fresh. So no, i don't consider myself a competent shell programmer. Shell is among the hardest languages to write good, secure code in. That's why i have re-rwitten the OpenBSD security(8) script, which used to be in sh(1) before my time, in perl(1), with contributions from Andrew Fresh. The security(8) acript is run from daily(8), which is a shell script that i have also significantly contributed to. > I believe I'm quite competent writing shell scripts. :) >> 3. they refuse to believe that the variety of possible deployment >> environments is as wide as it is. I think that was actually true thirty years ago, when many systems shipped shells that were badly starved for features and full of bugs and limitations. It was no longer true 15 years ago. Nobody has used Silurian systems in need of autoconf-style shell workarounds for at least a decade, probably much longer. Here is the list of systems where the configuration system described above is known to just work (sorted alphabetically): Adelie Linux Alpine Linux Arch Linux Chimera Linux Crux Linux Cygwin Debian DragonFly BSD Fedora FreeBSD Gentoo Guix System IBM AIX illumos IRIX macOS Minix 3 NetBSD NixOS OpenBSD openSUSE Oracle Solaris Slackware Linux Sun OS 5.9 Sun OS 5.10 Termux Ubuntu Unleashed OS Void Linux No shortage of weirdos in there, right? > I acknowledge this. However, some people refuse to believe that > hand-crafted makefiles can also handle quite different environments too. > I believe makefiles can do that just fine. It's a matter of how much > makefile code you write. > > In the Linux man-pages project, we have 120 kB of makefiles. > > $ find share/mk/ -type f | xargs wc -c GNUmakefile | tail -n1 > 119125 total That's an awful lot. Why would the man-pages Makefiles need to be more than seven times larger than the mandoc Makefiles? You don't even need to compile and link C code, right? > I believe that a set of makefiles that would handle all of the targets > of a project like groff wouldn't take much more than that. It might be > a few hundred kB. If it's well organized, it can be maintainable. Groff is definitely larger than either of man-pages and mandoc, and in particular uses a wider variety of languages and file format transformations. The factor might be larger than just two or three, but not orders of magnitude larger, that much i tend to agree with. > Because the makefile language is so simple, bugs are easy to spot and > fix, compared to autotools (possibly automake, but I can't distinguish > them enough). Strongly seconded. Due to the autotools it uses, the time i spend merely maintaining the GNU roff(7) port in OpenBSD, not even counting the times i have spent submitting patches to the upstream groff build system, is a very large factor (maybe about ten times) larger than all the time i ever spent on the mandoc build system, even though i wrote most of it from scratch and have been maintaining it for over 20 operating systems for over a decade. >> The build system is the thing that consistently gives us the most pain >> when trying to firm up a release. So right now you are pulling on HEAD >> at its most fragile, ironically. The code quality should be good, _if_ >> you can get the build to completion. That is in sharp contrast to my experience with the mandoc build system. When i send out release candidates for mandoc, almost all the feedback i get concerns real issues with the actual code itself, only a tiny fraction has to do with the files "Makefile" and "configure", and even those few issues are typically very easy to fix. > I'm happy to uncover those bugs; it's not a problem. That's also in sharp contrast to my experience. I have repeatedly spent considerable amounts of time fighting with the groff build system, i have never been happy about it, and the considerable loss of time it has often caused has been a problem that has often hampered progress on more productive topics related to groff and mandoc. Still, i do often track down such issues out of sheer necessity, because otherwise building just fails outright. All that said, i don't think revisiting the question of which build and portability system to use for groff is particularly productive at this time. Bertrand already did the work of automaking it, Branden is apparently reasonably content with the result (and comfort of the chief maintainer *is* the eminent consideration regarding a build system), so uprooting that beast once again is likely not advisable, unless Branden somehow becomes very frustrated with it. My motivation of sketching my experience here is mostly for Alejandro's personal benefit. Talking about releases, there is finally some progress: * I finally have a fully working port of groff-1.23 with no more unexplained discrepancies left. * I finally have mandoc in sync with groff-1.23 - well, not perfectly, but so far that i now understand all the remaining incompatibilities, in particular those that groff grew from 1.22.4 to 1.23. * I'm currently looking through the mandoc TODO list for things that can be fixed with little risk before release; i think there at at most very few. * After that, my next step will be sending out a mandoc-1.15.1 release candidate for testing, then release it. * After that, i will update the groff port to 1-23, then start more seriously looking at porting 1.24. * I will almost certainly *not* look at 1.25 before upgrading the port to 1.24 - last time, giving priority to release testing caused my progress on understanding new discrepancies in 1.23 to stall out, which probably wasn't ideal. Here is a draft of the NEWS file (temporary file name, will go away when the release candidates goes out) - just as a preview for you showing likely release content: https://mandoc.bsd.lv/NEWS.draft.txt I believe a few very weird bugs persist in the GNU tbl(1) formatter for terminal output, related to when exactly vertical lines between columns extend higher than the top of the table - apparently, the set of cases is even different from the set of cases where the vertical spacing before tables that Branden attempted to remove for 1.23 still persists, and there are a few cases in which vertical lines extend far (many lines) beyond the table, sometimes above, sometimes below. Then again, reporting those multiple weirdnesses properly will have to wait until after the update of the port to groff-1.23. If you are dying from curiosity, running the test file https://cvsweb.openbsd.org/checkout/src/regress/usr.bin/mandoc/tbl/layout/lines-nogroff.in?rev=1.2 through the mandoc gmdiff script (or just formatting it with groff and mandoc and diffing the results) may give you a rough idea, but i'm well aware this is *not* a proper bug report. I don't yet understand what the point of .LS is - in my experience, assembling items from .IP and .TP blocks to form lists is *not* among the problems the man(7) language causes - quite to the contrary, even though HTML is a strongly structural and semantic language, assembling even HTML code from .IP and .TP is a almost never a problem, and i don't see which other target format could possibly be harder to handle than HTML. I would probably have to read up on prior discussions, but the topic feels unrelated and i won't mix it into this mail. Yours, Ingo ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: autotools, was: Using LS/LE 2026-08-23 22:31 ` autotools, was: Using LS/LE Ingo Schwarze @ 2026-08-24 0:09 ` Alejandro Colomar 2026-08-29 4:36 ` G. Branden Robinson 1 sibling, 0 replies; 41+ messages in thread From: Alejandro Colomar @ 2026-08-24 0:09 UTC (permalink / raw) To: Ingo Schwarze; +Cc: g.branden.robinson, linux-man, groff [-- Attachment #1: Type: text/plain, Size: 13104 bytes --] Hallo Ingo! > Date: 2026-08-24 00:31:07+0200 > From: Ingo Schwarze <schwarze@usta.de> > > Hello Alejandro and Branden, > > Alejandro Colomar wrote on Sun, Aug 23, 2026 at 09:30:53PM +0200: > > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > > >> Autoconf, Automake, and Libtool, the collective "autotools", are all > >> strongly distinguishable in purpose. > > > I guess if you deal with them enough, you get to distinguish them. > > In shadow-utils, where we have an autotools-based build system, I > > consistently avoid to learn it. I leave it up to the other maintainers > > and the distro maintainers to keep it working. I only report the issues > > to them. To me, it'd be easier to wipe it all and write a Makefile from > > scratch than learning the tools. The day I have to maintain that, I'll > > probably do so. > > As one data point for Alejandro, that's precisely what i chose to do, > and not even because i had never used autoconf before, just because > i considered using autoconf massive overkill and likely to cause > a maintenance nightmare. The same applies to automake, but to > an even higher degree. Thanks for the data point! > Look at this: > > $ pwd > /co/mandoc > $ wc configure # handwritten, human-readable, and portable > 693 2537 20370 configure > $ wc Makefile # handwritten, human-readable, and portable > 619 1600 16050 Makefile > $ wc config.h # generated by ./configure > 54 150 1326 config.h Nice! > > Apart from that, there are 37 test-*.c feature test files, > all handwritten and human-readable, 723 lines grand total, > i.e. less than twenty lines on average. > > Finally, there are 19 compat_*.c portable replacement implementations > for systems lacking certain functions. That sounds like what I'd have expected. Thanks! [...] > >> 3. they refuse to believe that the variety of possible deployment > >> environments is as wide as it is. > > I think that was actually true thirty years ago, when many systems > shipped shells that were badly starved for features and full of bugs > and limitations. It was no longer true 15 years ago. Nobody > has used Silurian systems in need of autoconf-style shell workarounds > for at least a decade, probably much longer. > > Here is the list of systems where the configuration system described > above is known to just work (sorted alphabetically): > > Adelie Linux Alpine Linux Arch Linux Chimera Linux > Crux Linux Cygwin Debian DragonFly BSD > Fedora FreeBSD Gentoo Guix System > IBM AIX illumos IRIX macOS > Minix 3 NetBSD NixOS OpenBSD > openSUSE Oracle Solaris Slackware Linux Sun OS 5.9 > Sun OS 5.10 Termux Ubuntu Unleashed OS > Void Linux > > No shortage of weirdos in there, right? Indeed! :) > > I acknowledge this. However, some people refuse to believe that > > hand-crafted makefiles can also handle quite different environments too. > > I believe makefiles can do that just fine. It's a matter of how much > > makefile code you write. > > > > In the Linux man-pages project, we have 120 kB of makefiles. > > > > $ find share/mk/ -type f | xargs wc -c GNUmakefile | tail -n1 > > 119125 total > > That's an awful lot. Why would the man-pages Makefiles need to be > more than seven times larger than the mandoc Makefiles? The main make file is 1.7k (mainly, the help text); let's ignore that part. 20k of share/mk/ seems to be just the include's, so let's also ignore that part, since it doesn't affect readability much. $ find share/mk/ -type f | xargs cat | wc -c 117364 $ find share/mk/ -type f | xargs cat | grep -v ^include | wc -c 99476 From the remaining 100k, 22k are part of the linting system, which runs a lot of analyzers, both on the manual pages, and on the C examples. That's superfluous for actually building, so we could live without it. $ find share/mk/lint/ -type f | xargs cat | grep -v ^include | wc -c 21668 Here's a look at the directories: $ du -h -d1 -A share/mk/ 7.0K share/mk/install 2.7K share/mk/src 33K share/mk/build 8.0K share/mk/dist 26K share/mk/lint 2.5K share/mk/check 35K share/mk/configure 1.6K share/mk/help 115K share/mk/ The 'lint' target seems to be quite heavy. 'build-*' is also heavy, but it's more necessary. Although building the C programs is also done just for linting purposes, and wouldn't be necessary. Let's analyze that directory: $ du -h -d1 -A share/mk/build/ 1.4K share/mk/build/pre 12K share/mk/build/pdf 3.6K share/mk/build/catman 2.2K share/mk/build/html 3.2K share/mk/build/fonts 5.3K share/mk/build/examples 3.0K share/mk/build/ps 2.1K share/mk/build/man 33K share/mk/build/ Hmmm, actually the code for building the examples is actually small. The PDF book takes the largest amount of code: $ du -h -A share/mk/build/pdf/ 3.2K share/mk/build/pdf/pages 8.5K share/mk/build/pdf/book 12K share/mk/build/pdf/ $ ls -lh share/mk/build/pdf/book/ total 16K -rw-rw-r-- 1 alx alx 1.6K Aug 4 14:16 _.mk -rw-rw-r-- 1 alx alx 511 Aug 4 14:16 front.roff -rwxrwxr-x 1 alx alx 6.4K Aug 4 14:16 prepare.pl I build all that just to make sure it builds, but we don't need it either, and could perfectly live without building anything. The only code we really need from there is that which updates the date in the TH line, which is in $ ls -lh share/mk/build/man total 12K -rw-rw-r-- 1 alx alx 481 Aug 4 14:16 _.mk -rw-rw-r-- 1 alx alx 995 Aug 4 14:16 nonso.mk -rw-rw-r-- 1 alx alx 629 Aug 4 14:16 so.mk The remaining 31k of the build-* targets we could live without it. And then there's the configure/ subdir. That holds variables for the program names and their flags. I have CFLAGS-like variables for most programs, just in case we need to tweak them. Most of them are unnecessary, and we could live without them. We also have variables for every program (including things like CAT := cat). The nice thing about those variables is that I can list _all_ the dependencies of the build system, programatically. $ make -R help make: warning: undefined variable 'GNUMAKEFLAGS' Common targets: all Synonym of 'build' build Build the usual stuff build-all Build everything check Check the results of the build clean Remove all temporary files dist Produce the release tarball distcheck Check the release tarball help Print this help help-list-build-depends List build dependencies (package/program) help-list-targets List all targets help-list-variables List configurable variables install Install the usual stuff install-all Install everything lint Lint the source code nothing Do nothing; useful for debugging uninstall Uninstall everything (might leave traces) $ make -R help-list-build-depends | wc -l make: warning: undefined variable 'GNUMAKEFLAGS' 63 $ make -R help-list-build-depends | head -n1 make: warning: undefined variable 'GNUMAKEFLAGS' awk/awk Also, most of the dependencies would just vanish if we got rid of the lint target and didn't build the C programs, so this is in part just due to the lint/ subdir. I could certainly live with just 10% of this build system, but those extra targets have been useful to prevent introducing several regressions in the pages. Another important aspect of makefiles is that I *can* add all these lint targets just fine (they're just like any other targets). It's just a matter of adding some code; the more I want to lint, the more code, but it's not that hard. With autotools, I'd probably give up. It's already hard to make it just work for simply building, so linting is way beyond what one would support. > You don't even need to compile and link C code, right? Actually, I do. I build most of the C examples from the pages, and for that, I also had to add the Makefile code to extract them from the pages, so it's a bit more. > > I believe that a set of makefiles that would handle all of the targets > > of a project like groff wouldn't take much more than that. It might be > > a few hundred kB. If it's well organized, it can be maintainable. > > Groff is definitely larger than either of man-pages and mandoc, > and in particular uses a wider variety of languages and file > format transformations. The factor might be larger than just > two or three, but not orders of magnitude larger, that much i > tend to agree with. > > > Because the makefile language is so simple, bugs are easy to spot and > > fix, compared to autotools (possibly automake, but I can't distinguish > > them enough). > > Strongly seconded. Due to the autotools it uses, the time i spend > merely maintaining the GNU roff(7) port in OpenBSD, not even > counting the times i have spent submitting patches to the > upstream groff build system, is a very large factor (maybe > about ten times) larger than all the time i ever spent on the > mandoc build system, even though i wrote most of it from scratch > and have been maintaining it for over 20 operating systems for > over a decade. > > >> The build system is the thing that consistently gives us the most pain > >> when trying to firm up a release. So right now you are pulling on HEAD > >> at its most fragile, ironically. The code quality should be good, _if_ > >> you can get the build to completion. > > That is in sharp contrast to my experience with the mandoc build > system. When i send out release candidates for mandoc, almost > all the feedback i get concerns real issues with the actual code > itself, only a tiny fraction has to do with the files "Makefile" > and "configure", and even those few issues are typically very easy > to fix. > > > I'm happy to uncover those bugs; it's not a problem. > > That's also in sharp contrast to my experience. I have repeatedly > spent considerable amounts of time fighting with the groff build > system, i have never been happy about it, and the considerable > loss of time it has often caused has been a problem that has often > hampered progress on more productive topics related to groff and mandoc. I don't mind because I don't have to work with it often. I just try to build, and if it doesn't, I report it and move on to something else. I can certainly see how your opinion is different being a downstream packager, where you *have* to make it work, and have pressure to make it work rather soon. To me, if it doesn't build, I'll try the feature some other month. > Still, i do often track down such issues out of sheer necessity, > because otherwise building just fails outright. > > All that said, i don't think revisiting the question of which build > and portability system to use for groff is particularly productive > at this time. Bertrand already did the work of automaking it, > Branden is apparently reasonably content with the result (and comfort > of the chief maintainer *is* the eminent consideration regarding a > build system), so uprooting that beast once again is likely not > advisable, unless Branden somehow becomes very frustrated with it. > > My motivation of sketching my experience here is mostly for > Alejandro's personal benefit. Thanks! It's good to see some programmers share my opinion/concerns. In the past, I've received quite some pressure from distro/GNU people (mostly, Gentoo maintainers) pushing me to abandon the GNU Make hand-crafted build system in favour of their favourite tool (they offered autotools, then Meson), and I didn't enjoy that pressure at all. > Talking about releases, there is finally some progress: > > * I finally have a fully working port of groff-1.23 > with no more unexplained discrepancies left. > * I finally have mandoc in sync with groff-1.23 - > well, not perfectly, but so far that i now understand > all the remaining incompatibilities, in particular > those that groff grew from 1.22.4 to 1.23. --- MAJOR INCOMPATIBLE CHANGE FOR GROFF-1.23 COMPATIBILITY --- * man(7)/tbl(7): stop unconditionally emitting vertical space before .TS > * I'm currently looking through the mandoc TODO > list for things that can be fixed with little risk > before release; i think there at at most very few. > * After that, my next step will be sending out a mandoc-1.15.1 > release candidate for testing, then release it. --- MAJOR NEW FEATURES --- * man(1): use unveil(2) if provided by the operating system * mdoc(7): support .Lb libname [...] in the SYNOPSIS section * man(7): implement .MR (reference manual page), a groff-1.23 extension Nice! I'm waiting for that. :-) Have a lovely night! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE 2026-08-23 22:31 ` autotools, was: Using LS/LE Ingo Schwarze 2026-08-24 0:09 ` Alejandro Colomar @ 2026-08-29 4:36 ` G. Branden Robinson 2026-08-29 11:34 ` Ingo Schwarze 1 sibling, 1 reply; 41+ messages in thread From: G. Branden Robinson @ 2026-08-29 4:36 UTC (permalink / raw) To: Ingo Schwarze; +Cc: Alejandro Colomar, linux-man, groff [-- Attachment #1: Type: text/plain, Size: 4811 bytes --] Hi Ingo, At 2026-08-24T00:31:07+0200, Ingo Schwarze wrote: > I don't yet understand what the point of .LS is I have articulated clearly several specific points about it. I initially had the idea for LS/LE as early as December 2022. https://lists.gnu.org/archive/html/groff/2022-12/msg00075.html At that time, I got no feedback on my proposal, which I interpreted as indifference. That's the usual fate of my proposals. ;-) For example: https://lists.gnu.org/archive/html/groff/2026-07/msg00096.html Earlier this year, after list nesting caused Alex pain again, and having gotten more familiar with the bash(1) man page source, I consulted with Alex, Pádraig Brady (GNU coreutils), Stephen Gildea (help2man), and Chet Ramey (GNU Bash) regarding its interface, semantics, and goals. > - in my experience, assembling items from .IP and .TP blocks to form > lists is *not* among the problems the man(7) language causes - quite > to the contrary, Assembling a list is not difficult. Exercising control over indentation and inter-paragraph spacing (even just to turn it on and shut it off) as they apply to the items of lists, especially when nested, can get quite tedious. > even though HTML is a strongly structural and semantic language, > assembling even HTML code from .IP and .TP is a almost never a > problem, and i don't see which other target format could possibly > be harder to handle than HTML. I don't disagree there. To get groff man(7) to generate <ol>, <ul>, and <dl> elements as desired, I'm going to have to make other revisions to grohtml(1) first, because it insists on using HTML tables to mock up indentation.[1] I don't want that. So unfortunately I don't expect that improvement to element tagging in HTML output in groff 1.25, though I hope to get that done for 1.26. (All the other features of LS/LE are, and Alex just this week helped ensure that some bugs in it got stomped.) That's not really HTML's fault, but arises from groff's long tradition of swinging a Mario mallet to force its stream-based paradigmatic processing peg into HTML's block-structured hole. > I would probably have to read up on prior discussions, but the topic > feels unrelated and i won't mix it into this mail. groff's documentation attempts to motivate the macros' presence. groff_man(7): List enclosure macros Enclose paragraphing macros between LS and LE to identify them as list items. Doing so can mark them as “compact”, ease management of their indentation, and supply hints to the output driver to improve their rendering (as with HTML). Lists can be nested. (Sub)sectioning macro calls, and the end of the document, close all open lists. These macros are GNU extensions. .LS type [compactness [indentation]] (since groff 1.25) Start (or open) a list. type is one of “definition”, “enumerated”, or “itemized”. compactness is a Boolean value directing suppression of inter‐paragraph spacing between list items. indentation specifies an indentation amount for the body of each list item; it is then unnecessary to specify this argument to the list item macros. Use IP with a mark argument to represent an itemized or enumerated list item, and TP for a definition list item. Use IP without arguments to associate successive paragraphs with an existing list item; to these, inter‐paragraph spacing applies even in compact lists. .LE (since groff 1.25) End (or close) the most recent open list. NEWS: * The an (man) package offers new macros to ease the formatting of lists. Enclose paragraphing macros between `LS` and `LE` to identify them as list items. Doing so can mark them as "compact", ease management of their indentation, and supply hints to the output driver to improve their rendering (as with HTML). Lists can be nested. (Sub)sectioning macro calls, and the end of the document, close all open lists. See groff_man(7) for details, and groff_man_style(7) for an example. Thanks to Alex Colomar, Chet Ramey, Pádraig Brady, and Stephen Gildea for consultation and encouragement, and to Alex for selecting these macros' names. Because these macros format no text, documents employing them risk no damage to their content if the formatter does not support them. A man(7) document author can choose either to transition to these macros, to manage list "compactness" and item indentation with existing man(7) package facilities, or to employ both approaches. Regards, Branden [1] https://savannah.gnu.org/bugs/?68424 [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE 2026-08-29 4:36 ` G. Branden Robinson @ 2026-08-29 11:34 ` Ingo Schwarze 2026-08-29 12:51 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: Ingo Schwarze @ 2026-08-29 11:34 UTC (permalink / raw) To: g.branden.robinson; +Cc: Alejandro Colomar, linux-man, groff Hi Branden, G. Branden Robinson wrote on Fri, Aug 28, 2026 at 11:36:15PM -0500: > At 2026-08-24T00:31:07+0200, Ingo Schwarze wrote: >> I don't yet understand what the point of .LS is > I have articulated clearly several specific points about it. I > initially had the idea for LS/LE as early as December 2022. > > https://lists.gnu.org/archive/html/groff/2022-12/msg00075.html > > At that time, I got no feedback on my proposal, If i remember correctly, i read that message as "i don't have clear goals, i don't have clear plans, and i don't see much need", so i saw no need to respond. > which I interpreted as indifference. > That's the usual fate of my proposals. ;-) Well, sometimes some people (including myself) do consider your proposals. :) > For example: > https://lists.gnu.org/archive/html/groff/2026-07/msg00096.html I missed that one, i wasn't around much in July. Not sure whether that's needed from a general-purpose typesetting perspective, i would have to think about that. For manual pages, that .ref proposal sounds like massive overengineering. It's simply not needed because almost all such information can be derived directly from the semantic manual page macros - and that's not theoretical speculation, mandoc(1) contains a mature implementation that is several years old by now. While mdoc(7) in mandoc does provide the .Tg macro, it is very rarely needed: currently, there are 214 instances of .Tg in OpenBSD /usr/share/man/, even though that directory contains 4635 manual pages, that's one instance in over 20 manual pages on average. Only 9 out of 4635 manualpages use the .Tg macro at all, which is less than two permille. > Earlier this year, after list nesting caused Alex pain again, Oh yes, that is true. The man(7) language doesn't really support nested lists well. > and having gotten more familiar with the bash(1) man page source, > I consulted with Alex, Pádraig Brady (GNU coreutils), > Stephen Gildea (help2man), and Chet Ramey (GNU Bash) regarding > its interface, semantics, and goals. >> - in my experience, assembling items from .IP and .TP blocks to form >> lists is *not* among the problems the man(7) language causes - quite >> to the contrary, > Assembling a list is not difficult. Exercising control over > indentation and inter-paragraph spacing (even just to turn it on and > shut it off) as they apply to the items of lists, especially when > nested, can get quite tedious. Again, that is true. The mandoc(1) -T man output mode uses .RS at the beginning and .RE at the end of each list to set up the indentation, and in nested lists, it uses .RS after the end of an inner list to get back to the indentation of the outer list. It uses .PD 0 whenever following paragraph(s) want no leading vertical space and .PD with no arguments whenever following paragraphs want normal vertical spacing again. That being tedious is a direct consequence of man(7) being more of a presentational than semantic language. >> even though HTML is a strongly structural and semantic language, >> assembling even HTML code from .IP and .TP is a almost never a >> problem, and i don't see which other target format could possibly >> be harder to handle than HTML. > I don't disagree there. To get groff man(7) to generate <ol>, <ul>, and > <dl> elements as desired, I'm going to have to make Well, mandoc -man -T html already generates (see man_html.c) <dl> or <ul> from .IP and .TP, since 2019: date: 2019/03/02 16:29:49; author: schwarze; lines: +68 -16 Represent multiple subsequent .IP blocks having a consistent head argument of *, \-, or \(bu as <ul> rather than as <dl>, using a bit of heuristics. Basic idea suggested by Dagfinn Ilmari Mannsaker <ilmari at github> in https://github.com/Debian/debiman/issues/67 and independently by <Pali dot Rohar at gmail dot com> on <discuss at mandoc dot bsd dot lv>. > other revisions to > grohtml(1) first, because it insists on using HTML tables to mock up > indentation.[1] I don't want that. So unfortunately I don't expect > that improvement to element tagging in HTML output in groff 1.25, though > I hope to get that done for 1.26. (All the other features of LS/LE are, > and Alex just this week helped ensure that some bugs in it got stomped.) > > That's not really HTML's fault, but arises from groff's long tradition > of swinging a Mario mallet to force its stream-based paradigmatic > processing peg into HTML's block-structured hole. >> I would probably have to read up on prior discussions, but the topic >> feels unrelated and i won't mix it into this mail. > groff's documentation attempts to motivate the macros' presence. > > groff_man(7): > List enclosure macros > Enclose paragraphing macros between LS and LE to identify them as > list items. Doing so can mark them as "compact", ease management > of their indentation, and supply hints to the output driver to > improve their rendering (as with HTML). Lists can be nested. > (Sub)sectioning macro calls, and the end of the document, close all > open lists. Do you recommend closing open lists before ending the section, or do you recommend dropping the .LE if it happens to be at the end of a section? This sentence sounds like the latter. I would probably strongly recommend the former and have the macro set warn about missing .LE because many years of experience show that forgotten list end macros are a widespread oversight among manual page authors, often causing the list to run further than intended. For that reason, having the warning about missing .LE seems important. > These macros are GNU extensions. Using these macros is probably less disruptive than using .MR, because lack of support in the formatter will only ruin spacing and indentation but not corrupt the text. Considering that the benefit of .LS/.LE is relatively minor, it was indeed important to choose such a conservative design. > .LS type [compactness [indentation]] What is the logical reason for requiring that, to specify the indentation, you also need to specify the compactness? > (since groff 1.25) Start (or open) a list. type is one of > "definition", "enumerated", or "itemized". compactness is a > Boolean value directing suppression of inter-paragraph > spacing between list items. That sounds very confusing. Does "Boolean" mean: either the string "0" or the string "1"? Or what would "true" or "false" mean? Then, "Boolean value directing suppression" sounds vaguely as if "1" might mean "suppress", but that's not expressed unambiguously. Finally, why only *between* list items? Why not *before each* list item? Would suppressing the vertical spacing before the first list item still require .PD 0 *in addition* to "compact"? > indentation specifies an > indentation amount for the body of each list item; it is > then unnecessary to specify this argument to the list item > macros. That sounds as if the syntax of "indentation" is probably the same as for the .IP and .TP "width" argument, but that is not clearly stated. So, what is the syntax? > Use IP with a mark argument to represent an > itemized or enumerated list item, and TP for a definition > list item. Use IP without arguments to associate > successive paragraphs with an existing list item; to these, > inter-paragraph spacing applies even in compact lists. Not sure the phrase staring with "to these" should be advertised so prominently. *If* an author chooses to make a list "compact" but then kind of contradicts themselves by inserting paragraph breaks into individual list items, the behaviour you describe is probably what the formatter should do. But authors ought to be strongly discouraged from doing that. When one or more items of your list are so complicated that they require more than one paragraph of text, making your list "compact" makes no sense in the first place and will result in ugly and confusing typography. To summarize, after reviewing the design of .LS/.LE, my first impression is that it is likely a small-value, small-harm addition. I think i will support them in mandoc(1) -man when i find the time, but not emit them from mandoc(1) -T man, at least not for many years to come, because the whole point of that output mode is dealing with operating systems that use ancient manual page formatters, and those are unlikely to support .LS/.LE. Chances are the the deeper scrutiny that will be necessary to implement .LS/.LE in mandoc(1) may lead to additional criticism; or if we are lucky, it may not. Yours, Ingo ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE 2026-08-29 11:34 ` Ingo Schwarze @ 2026-08-29 12:51 ` Alejandro Colomar 2026-08-29 19:16 ` G. Branden Robinson 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 12:51 UTC (permalink / raw) To: Ingo Schwarze; +Cc: g.branden.robinson, linux-man, groff [-- Attachment #1: Type: text/plain, Size: 3746 bytes --] Hi Ingo, > Date: 2026-08-29 13:34:55+0200 > From: Ingo Schwarze <schwarze@usta.de> > [...] > The mandoc(1) -T man output mode uses > [...] Oh, there's a -Tman mode! That's interesting! Some years ago, I wondered whether groff(1) could have a -Troff mode, which would evaluate the man(7) (or any other -m macros, FWIW) macros without formatting the document. This -Tman from mandoc(1) sounds like a similar (but not same, of course) thing. [...] > > .LS type [compactness [indentation]] > > What is the logical reason for requiring that, to specify the > indentation, you also need to specify the compactness? I guess I'd have the same question if it were the other way around, and this way I expect it's simple to implement (I'd certainly be more worried if groff(1) attempted to guess the meaning of my argument if I only pass one of them), so I think I'm okay with it. Do you have any ideas for a better interface? > > (since groff 1.25) Start (or open) a list. type is one of > > "definition", "enumerated", or "itemized". compactness is a > > Boolean value directing suppression of inter-paragraph > > spacing between list items. > > That sounds very confusing. Does "Boolean" mean: either the string "0" > or the string "1"? Or what would "true" or "false" mean? > Then, "Boolean value directing suppression" sounds vaguely as if "1" > might mean "suppress", but that's not expressed unambiguously. Agree. > Finally, why only *between* list items? Why not *before each* > list item? Would suppressing the vertical spacing before the first > list item still require .PD 0 *in addition* to "compact"? The idea, I think, is that if you write '.P' surriounding LS/LS, you'll get the outer blanks, and if not, you'll get compactness also before and/or after the list. [...] > > Use IP with a mark argument to represent an > > itemized or enumerated list item, and TP for a definition > > list item. Use IP without arguments to associate > > successive paragraphs with an existing list item; to these, > > inter-paragraph spacing applies even in compact lists. > > Not sure the phrase staring with "to these" should be advertised > so prominently. *If* an author chooses to make a list "compact" > but then kind of contradicts themselves by inserting paragraph > breaks into individual list items, the behaviour you describe is > probably what the formatter should do. I'm not convinced about this detail either. I think in a compact list this should not produce a blank line: .P .LE But this should: .LE .P > But authors ought to be strongly discouraged from doing that. > When one or more items of your list are so complicated that they > require more than one paragraph of text, making your list "compact" > makes no sense in the first place and will result in ugly and > confusing typography. +1 > To summarize, after reviewing the design of .LS/.LE, my first > impression is that it is likely a small-value, small-harm > addition. I think i will support them in mandoc(1) -man when > i find the time, but not emit them from mandoc(1) -T man, at least > not for many years to come, because the whole point of that output > mode is dealing with operating systems that use ancient > manual page formatters, and those are unlikely to support .LS/.LE. Makes sense. > Chances are the the deeper scrutiny that will be necessary to > implement .LS/.LE in mandoc(1) may lead to additional criticism; > or if we are lucky, it may not. Have a lovely day! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE 2026-08-29 12:51 ` Alejandro Colomar @ 2026-08-29 19:16 ` G. Branden Robinson 2026-08-29 21:43 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: G. Branden Robinson @ 2026-08-29 19:16 UTC (permalink / raw) To: Ingo Schwarze, Alejandro Colomar; +Cc: linux-man, groff [-- Attachment #1: Type: text/plain, Size: 23948 bytes --] Hi Ingo & Alex, At 2026-08-29T13:34:55+0200, Ingo Schwarze wrote: > G. Branden Robinson wrote on Fri, Aug 28, 2026 at 11:36:15PM -0500: > > At 2026-08-24T00:31:07+0200, Ingo Schwarze wrote: > > >> I don't yet understand what the point of .LS is > > > I have articulated clearly several specific points about it. I > > initially had the idea for LS/LE as early as December 2022. > > > > https://lists.gnu.org/archive/html/groff/2022-12/msg00075.html > > > > At that time, I got no feedback on my proposal, > > If i remember correctly, i read that message as "i don't have clear > goals, i don't have clear plans, and i don't see much need", > so i saw no need to respond. Fair enough. I shelved the item for over 3 years and finally it accumulated enough of all three to be actionable. > > which I interpreted as indifference. > > That's the usual fate of my proposals. ;-) > > Well, sometimes some people (including myself) do consider your > proposals. :) > > > For example: > > https://lists.gnu.org/archive/html/groff/2026-07/msg00096.html > > I missed that one, i wasn't around much in July. > Not sure whether that's needed from a general-purpose typesetting > perspective, i would have to think about that. [begin brief excursion off of LS/LE] That's the whole point of it. The context of the argument between Deri and me was driven by his enhancement of the ms(7) package to better support PDF features, including internal bookmarks. It's long been a goal to do the same for all of groff's full-service macro packages, which basically means tackling me(7) and mm(7) as well, since mom(7) already has such support. > For manual pages, that .ref proposal sounds like massive > overengineering. There's more to groff's world than man pages. I'm snipping the rest of this paragraph because your focus is misdirected. If we ever need hyperlinked internal bookmarks in man pages, mdoc(7) already has `Sx` and I have no problem adding a `SX` to man(7). The point of the machinery is to solve the forward reference problem. You are essentially saying that _any_ two-pass assembler is "massively overengineered" compared to a one-pass one. That is not the consensus of the field. A one-pass assembler simply cannot resolve forward references. It has only "errata". Achieving with a second design what was flatly impossible for the first does not constitute "overengineering" to me. What decides the issue is your selection of problems to solve. [end brief excursion off of LS/LE] > > Earlier this year, after list nesting caused Alex pain again, > > Oh yes, that is true. The man(7) language doesn't really support > nested lists well. Right. > > and having gotten more familiar with the bash(1) man page source, > > I consulted with Alex, Pádraig Brady (GNU coreutils), > > Stephen Gildea (help2man), and Chet Ramey (GNU Bash) regarding > > its interface, semantics, and goals. > > >> - in my experience, assembling items from .IP and .TP blocks to > >> form lists is *not* among the problems the man(7) language causes - > >> quite to the contrary, > > > Assembling a list is not difficult. Exercising control over > > indentation and inter-paragraph spacing (even just to turn it on and > > shut it off) as they apply to the items of lists, especially when > > nested, can get quite tedious. > > Again, that is true. > > The mandoc(1) -T man output mode uses .RS at the beginning and .RE > at the end of each list to set up the indentation, and in nested > lists, it uses .RS after the end of an inner list to get back to > the indentation of the outer list. It uses .PD 0 whenever > following paragraph(s) want no leading vertical space and .PD with > no arguments whenever following paragraphs want normal vertical > spacing again. > > That being tedious is a direct consequence of man(7) being more of > a presentational than semantic language. Right, and when a machine takes care of the tedium, that's just about bearable. But it's not when a human has to handle the tedium. > >> even though HTML is a strongly structural and semantic language, > >> assembling even HTML code from .IP and .TP is a almost never a > >> problem, and i don't see which other target format could possibly > >> be harder to handle than HTML. > > > I don't disagree there. To get groff man(7) to generate <ol>, <ul>, > > and <dl> elements as desired, I'm going to have to make > > Well, mandoc -man -T html already generates (see man_html.c) <dl> > or <ul> from .IP and .TP, since 2019: > > date: 2019/03/02 16:29:49; author: schwarze; lines: +68 -16 > Represent multiple subsequent .IP blocks having a consistent > head argument of *, \-, or \(bu as <ul> rather than as <dl>, > using a bit of heuristics. > > Basic idea suggested by Dagfinn Ilmari Mannsaker <ilmari at github> > in https://github.com/Debian/debiman/issues/67 and independently by > <Pali dot Rohar at gmail dot com> on <discuss at mandoc dot bsd dot > lv>. Acknowledged. I didn't want to use heuristics. To quote the Tao^WZen of Python: "Explicit is better than implicit."[1] > > groff's documentation attempts to motivate the macros' presence. > > > > groff_man(7): > > List enclosure macros > > Enclose paragraphing macros between LS and LE to identify them > > as list items. Doing so can mark them as "compact", ease > > management of their indentation, and supply hints to the output > > driver to improve their rendering (as with HTML). Lists can be > > nested. (Sub)sectioning macro calls, and the end of the > > document, close all open lists. > > Do you recommend closing open lists before ending the section, > or do you recommend dropping the .LE if it happens to be at the end > of a section? I make no recommendation here. Personally I follow the aforementioned Zen of Python in man(7) composition. Or would, if I had cause to use nested lists in groff's own man pages. I haven't yet. > This sentence sounds like the latter. No, I'm not trying to imply a preference for either. If I ever have a reason to recommend one practice over the other, I will do so. Until then, my intention is simply to observe the community and see what patterns arise in use. > I would probably strongly recommend the former and have the macro set > warn about missing .LE because many years of experience show that > forgotten list end macros are a widespread oversight among manual page > authors, often causing the list to run further than intended. > For that reason, having the warning about missing .LE seems > important. I would agree if `LS`/`LE` weren't designed to be harmlessly skippable by the many implementations that don't recognize them, including previous versions of groff and mandoc(1). > > These macros are GNU extensions. > > Using these macros is probably less disruptive than using .MR, > because lack of support in the formatter will only ruin spacing > and indentation but not corrupt the text. Considering that the > benefit of .LS/.LE is relatively minor, it was indeed important > to choose such a conservative design. Yes, that's my view. > > .LS type [compactness [indentation]] > > What is the logical reason for requiring that, to specify the > indentation, you also need to specify the compactness? * Employing a compactness flag is what kills off 99%+ of all uses I have observed of the `PD` macro. I seek to exterminate `PD`. * The man(7) writer can always specify an indentation explicitly as an argument to the `IP` and `TP` calls comprising the list items, and many will anyway, either for portability to mandoc(1) and older groff, or because they're simply accustomed to doing so. * In many cases I find explicit specification of an indentation amount to be unnecessary. A man(7) author should refrain from doing so unless readers are confused by the default indentation. That will be rare. There _is_ a population of man(7) authors, including myself in groff's man pages, who wish to fiddle the typography with precision. But that population is small. I'm trying to nudge the bulk of man(7) authors who _don't_ care about those details, and who often resent writing a man page at all, from specifying parameters they will tell you out loud that they don't care about. If they feel forced to choose a value, they will much more often than not pick a lousy one, because there _is_ an art to laying out a page, and artistry demands intention, practice, and taste. * Contriving a new syntax for man(7) macro arguments, like mdoc(7)'s `-centered`, `-filled`, `-literal`, `-ragged`, and so forth, which look like X11-style Unix command-line options, is a major anti-goal of mine. Nothing in man(7) looks like that and I mean not to make it start. In fact I think this is a bad idea in macro package design because the superficial resemblance to the Unix command line is misleading and will be overinterpreted by users. I deplore mm(7) and especially mdoc(7) for chasing this blinkered pseudosymmetry. man(7)'s macro argument handling is simple and positional, and I mean to keep it that way. * I'm already having to innovate more than I care for with the "literal word" argument in the first position, "definition", "enumerated", or "itemized". In 1979 this certainly would have been spelled using an integer mapping, or maybe by abbreviation to a single letter. But such an encoding is a bad idea, driven by the punitive nature of operating a Teletype machine as a terminal. By using a whole English word, the reader can likely infer what the macro call is doing even if they never read the package's man page. On a related note, Ada and modern Fortran use language keywords excellently. C and C++ use them horribly; practitioners of these language pride themselves on knowing what `static`, `restrict` and `auto` mean in multiple contexts and across revisions of the language standard. If we were honest, we'd recognize ourselves as objects of pity, having cheerfully invited Ritchie and Stroustrup to bury axe blades in our skulls, and then touting our ability to endure pointless punishment as a personal virtue to prospective tech sector employers. > > (since groff 1.25) Start (or open) a list. type is one > > of "definition", "enumerated", or "itemized". > > compactness is a Boolean value directing suppression of > > inter-paragraph spacing between list items. > > That sounds very confusing. Does "Boolean" mean: either the string > "0" or the string "1"? Or what would "true" or "false" mean? Then, > "Boolean value directing suppression" sounds vaguely as if "1" might > mean "suppress", but that's not expressed unambiguously. You're right; this is the only occurrence of "Boolean" in groff_man(7) and I need to fix that. I was carrying over a practice from my revisions to the groff_mm(7) page, where integral, Boolean-valued macro arguments are idiomatic. I'll clarify this. Thanks! > Finally, why only *between* list items? Why not *before each* > list item? Because there is already a mechanism for achieving that. > Would suppressing the vertical spacing before the first list item > still require .PD 0 *in addition* to "compact"? No, `.PD 0` is never required under this design; this was an essential trait since one of my objectives is to exterminate the `PD` macro in the wild. One can still _use_ `PD` calls in parallel with `LS`/`LE` if one likes, and I expect bash(1) to do so, assuming Chet doesn't get cold feet on using `LS`/`LE` at all. But, if you mess up your `PD` calls such that compactness breaks, that's on you. > > indentation specifies an indentation amount for the body > > of each list item; it is then unnecessary to specify > > this argument to the list item macros. > > That sounds as if the syntax of "indentation" is probably the same > as for the .IP and .TP "width" argument, but that is not clearly > stated. So, what is the syntax? One can profitably look at the `IP` and `TP` macro descriptions in the same document and perceive the parallel usage. .TP [indentation] Set an indented paragraph with a leading unindented tag. The macro plants a one‐line input trap that honors the \c escape sequence; text on the next line becomes the tag, set without indentation. Text on subsequent lines is indented by indentation, if specified, and by the amount of the IN register otherwise. If the tag, plus the “tag spacing” stored in the TS register (see section “Options” below) is wider than the indentation, the package breaks the line after the tag. ... .IP [mark [indentation]] Set an indented paragraph with an optional mark. Arguments, if present, are handled as with TP, except that the mark argument to IP cannot include a macro call, and the tag separation amount stored in the TS register is not enforced. > > Use IP with a mark argument to represent an itemized or > > enumerated list item, and TP for a definition list item. > > Use IP without arguments to associate successive > > paragraphs with an existing list item; to these, > > inter-paragraph spacing applies even in compact lists. > > Not sure the phrase staring with "to these" should be advertised so > prominently. *If* an author chooses to make a list "compact" but then > kind of contradicts themselves by inserting paragraph breaks into > individual list items, the behaviour you describe is probably what the > formatter should do. > > But authors ought to be strongly discouraged from doing that. When > one or more items of your list are so complicated that they require > more than one paragraph of text, making your list "compact" makes no > sense in the first place and will result in ugly and confusing > typography. This detail was motivated by the presence of this exact pattern in the bash(1) man page, which does indeed employ multi-paragraph compact list items. I am mindful of my distinct roles as groff maintainer and macro package programmer on the one hand, and as a coach/advisor on man page composition practices on the other. Put differently, I have implemented `LS`/`LE` to provide mechanism. I cannot use that mechanism to dictate policy; only to make "good policy" easier to practice. > To summarize, after reviewing the design of .LS/.LE, my first > impression is that it is likely a small-value, small-harm > addition. I agree. Most man(7) documents don't mess with nested lists. But I needed a non-heuristic means to smuggle semantic information about list properties to the grohtml(1) output driver, and saw a couple of other birds I could kill with the same stone. > I think i will support them in mandoc(1) -man when > i find the time, but not emit them from mandoc(1) -T man, at least > not for many years to come, because the whole point of that output > mode is dealing with operating systems that use ancient > manual page formatters, and those are unlikely to support .LS/.LE. That sounds fine, but, hmm, if you're already heuristically computing when to bracket list items with `.PD 0` and `.PD`, you're already doing most of the work it would take to emit `LS` and `LE`. But I don't think it matters much. > Chances are the the deeper scrutiny that will be necessary to > implement .LS/.LE in mandoc(1) may lead to additional criticism; > or if we are lucky, it may not. Fingers crossed. At 2026-08-29T14:51:44+0200, Alejandro Colomar wrote: > Hi Ingo, > > > Date: 2026-08-29 13:34:55+0200 > > From: Ingo Schwarze <schwarze@usta.de> > > > [...] > > The mandoc(1) -T man output mode uses > > [...] > > Oh, there's a -Tman mode! That's interesting! Some years ago, > I wondered whether groff(1) could have a -Troff mode, which would > evaluate the man(7) (or any other -m macros, FWIW) macros without > formatting the document. I know of no troff that permits this. In interpretation mode (that is, "not copy mode"), interpolation and transformation of tokens to nodes are both operations that occur at the earliest possible opportunity while interpreting the input stream. In the past year or so I have revised groff's Texinfo manual to give the formatter's internals better coverage. ---snip--- 5.37 GNU 'troff' Internals ========================== GNU 'troff' processes input in three steps. It gathers one or more input characters into a "token",(1) (*note GNU troff Internals-Footnote-1::) the smallest meaningful unit of 'troff' input. The process of formatting translates tokens into nodes that populate a pending output line (recall *note Manipulating Filling and Adjustment::). A "node" is a data structure representing any object that may ultimately appear in the output, like a glyph or motion on the page. When the pending output line breaks, the formatter applies any relevant adjustment, line number, and margin character, and finally appends it to the current diversion. Periodically, the formatter "flushes" accumulated output line(s) to the output device, a process that translates each node into a device-independent output language representation understood by all output drivers. Copy mode tokenizes but does not format; diversions (apart from that at the top level) format but do not write output. For example, GNU 'troff' converts the input 'Gi\[:u]\%seppe' into a character token for 'g', a character token for 'i', a special character token for ':u' (representing 'u' with an umlaut), a token encoding a hyphenation point,(2) (*note GNU troff Internals-Footnote-2::) and further character tokens. You can observe this process by storing the foregoing input into a string--which, because its contents are read in copy mode, is only tokenized, not formatted--and dumping it with the 'pm' request.(3) (*note GNU troff Internals-Footnote-3::) (Using 'printf(1)' requires us to double the '\' and '%' characters.) $ printf '.ds str Gi\\[:u]\\%%seppe\n.pm str\n' \ | groff 2>&1 | jq Similarly, we can observe the details of the formatting process by interpolating the string, or supplying its contents directly as input, and invoking the 'pline' request. $ printf 'Gi\\[:u]\\%%seppe\n.pline\n' | groff -z 2>&1 | jq We now see a list of nodes, including an output line start node, several glyph nodes, a discretionary break node containing a glyph node for the special character ':u' _and_ a glyph node for the special character 'hy' (hyphen), and a word space node at the end corresponding to the newline at the end of input.(4) (*note GNU troff Internals-Footnote-4::) If we change 'G' to 'f', we see that the first two glyph nodes, for 'f' and 'i', become contained by a ligature node (provided the current font has a glyph for this ligature). All output glyph nodes are "processed", which means that they are associated with a given font, type size, advance width, and so forth. ... ---end snip---- GNU troff's ability to recursively dump string/macro/diversion, user-defined character, and pending output line contents as a forest of JSON nodes was a major new feature of groff 1.24. It's not the same thing by any means as a "wholly macro expanded document", but given how dynamic a language *roff is, I'm not sure the goal you had in mind is possible. A language theorist might be able to help me devise a proof one way or the other. Nevertheless, the recursive node dumping feature, as with other new debugging requests in groff 1.24, forces the formatter to disclose the truth about its internal state to a degree unprecedented in *roff. (I'll just be shampooing out the pomade and taking this plaid blazer off now, thanks.) > [...] > > Finally, why only *between* list items? Why not *before each* > > list item? Would suppressing the vertical spacing before the first > > list item still require .PD 0 *in addition* to "compact"? > > The idea, I think, is that if you write '.P' surriounding LS/LS, > you'll get the outer blanks, and if not, you'll get compactness also > before and/or after the list. Yes. > > Not sure the phrase staring with "to these" should be advertised > > so prominently. *If* an author chooses to make a list "compact" > > but then kind of contradicts themselves by inserting paragraph > > breaks into individual list items, the behaviour you describe is > > probably what the formatter should do. > > I'm not convinced about this detail either. I think in a compact list > this should not produce a blank line: > > .P > .LE > > But this should: > > .LE > .P I disagree. As presently implemented, they're equivalent. A `P` paragraph _does not mark a list item_. Only `IP` and `TP` do. I wanted to support the case where a list is interrupted by a paragraph. It's not uncommon in technical writing. Here's a contrived example. $ cat ATTIC/blertch.man .TH blertch 7 2026-08-29 "Blertch language reference" .SH Name blertch \- a fake language for fake programmers .SH Description The Blertch language supports the following operators. .P .LS definition 1 \" compact .TP .B a + b .TP .B a \- b .TP .B a * b .TP .B a / b .TP .B a % b .P It also supports the unary plus and minus operators. .P .TP .B +a .TP .B \-a .LE .P Operator overloading is not implemented. $ nroff -rLL=72n -man ATTIC/blertch.man blertch(7) Miscellaneous Information Manual blertch(7) Name blertch - a fake language for fake programmers Description The Blertch language supports the following operators. a + b a - b a * b a / b a % b It also supports the unary plus and minus operators. +a -a Operator overloading is not implemented. Blertch language reference 2026‐08‐29 blertch(7) I can imagine a counterargument. "But why support interrupting the list that way? It's _really_ two lists, so the document author should have to close off the first list with `LE`, do their 'interrupting' paragraph, then start a new list with `LS`." I say no. The purpose of the macro package is to serve the technical writer and aid them to communicate. It is not to serve the HTML/XML weenie who wants all their tags nested in some canonical fashion. Sometimes, technological constraints will propagate backward to our language designs. But that's a phenomenon to be regretted, not leaned into. It's certainly possible that, when I revise grohtml(1) to support output of the foregoing, I'll have to break this into two HTML lists. If so, that's fine. That's where the problem _should_ be solved. It should not be back-propagated onto the document author if we can help it. > > But authors ought to be strongly discouraged from doing that. > > When one or more items of your list are so complicated that they > > require more than one paragraph of text, making your list "compact" > > makes no sense in the first place and will result in ugly and > > confusing typography. > > +1 Again, this is a matter of policy, not mechanism. My focus in implementing this feature is on the latter. Regards, Branden [1] https://peps.python.org/pep-0020/ [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE 2026-08-29 19:16 ` G. Branden Robinson @ 2026-08-29 21:43 ` Alejandro Colomar 0 siblings, 0 replies; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 21:43 UTC (permalink / raw) To: G. Branden Robinson; +Cc: Ingo Schwarze, linux-man, groff [-- Attachment #1: Type: text/plain, Size: 3010 bytes --] Hi Branden, > Date: 2026-08-29 14:16:39-0500 > From: "G. Branden Robinson" <g.branden.robinson@gmail.com> > [...] > > > The mandoc(1) -T man output mode uses > > > [...] > > > > Oh, there's a -Tman mode! That's interesting! Some years ago, > > I wondered whether groff(1) could have a -Troff mode, which would > > evaluate the man(7) (or any other -m macros, FWIW) macros without > > formatting the document. > > I know of no troff that permits this. In interpretation mode (that is, > "not copy mode"), interpolation and transformation of tokens to nodes > are both operations that occur at the earliest possible opportunity > while interpreting the input stream. > > In the past year or so I have revised groff's Texinfo manual to give the > formatter's internals better coverage. > > ---snip--- [...] > ---end snip---- > > GNU troff's ability to recursively dump string/macro/diversion, > user-defined character, and pending output line contents as a forest of > JSON nodes was a major new feature of groff 1.24. > > It's not the same thing by any means as a "wholly macro expanded > document", but given how dynamic a language *roff is, I'm not sure the > goal you had in mind is possible. A language theorist might be able to > help me devise a proof one way or the other. > > Nevertheless, the recursive node dumping feature, as with other new > debugging requests in groff 1.24, forces the formatter to disclose the > truth about its internal state to a degree unprecedented in *roff. > > (I'll just be shampooing out the pomade and taking this plaid blazer off > now, thanks.) I'll keep poking you about it from time to time, hoping some day you'll have the internal tools to implement this. :) [...] > Description > The Blertch language supports the following operators. > > a + b > a - b > a * b > a / b > a % b > > It also supports the unary plus and minus operators. > > +a > -a > > Operator overloading is not implemented. > > Blertch language reference 2026‐08‐29 blertch(7) > > I can imagine a counterargument. > > "But why support interrupting the list that way? It's _really_ two > lists, so the document author should have to close off the first list > with `LE`, do their 'interrupting' paragraph, then start a new list with > `LS`." Indeed, I believe this is two lists. > I say no. > > The purpose of the macro package is to serve the technical writer and > aid them to communicate. It is not to serve the HTML/XML weenie who > wants all their tags nested in some canonical fashion. Sometimes, > technological constraints will propagate backward to our language > designs. But that's a phenomenon to be regretted, not leaned into. Hmmmm, I'm not convinced we should support this, but I don't care too much about it either. Have a lovely night! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
[parent not found: <8DE76435-CBDB-42D6-9E0F-9E27291560B6@icloud.com>]
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) [not found] ` <8DE76435-CBDB-42D6-9E0F-9E27291560B6@icloud.com> @ 2026-08-29 8:42 ` Alejandro Colomar 2026-08-29 8:45 ` Alejandro Colomar 2026-08-29 9:39 ` Ingo Schwarze 1 sibling, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 8:42 UTC (permalink / raw) To: Larry Kollar; +Cc: Groff, linux-man [-- Attachment #1: Type: text/plain, Size: 1907 bytes --] Hi Larry, > Date: 2026-08-28 22:50:50-0400 > From: Larry Kollar <larry.kollar@icloud.com> > > > Alejandro Colomar <alx@kernel.org> wrote: > > > I believe that a set of makefiles that would handle all of the targets > > of a project like groff wouldn't take much more than that. It might be > > a few hundred kB. If it's well organized, it can be maintainable. > > > > Because the makefile language is so simple, bugs are easy to spot and > > fix, compared to autotools (possibly automake, but I can't distinguish > > them enough). > > I don’t know. Can a Makefile check for the presence of certain libraries > or other apps and fail gracefully (by which I mean exiting with a message > like “You need app X, plus libraries Y and Z, installed to successfully > compile this.”)? That’s one of the things that “makes" me appreciate taking > that extra step of typing `.configure` before make. Yes, it can. Here's a trivial test for that: alx@devuan:~/tmp/testlib$ cat Makefile HAS_LIBFOO := $(shell find /usr/include/foo.h >/dev/null && echo yes || echo no) ifeq ($(HAS_LIBFOO),no) $(error You need library FOO installed to successfully compile this.) endif all: echo Done alx@devuan:~/tmp/testlib$ make find: ‘/usr/include/foo.h’: No such file or directory Makefile:4: *** You need library FOO installed to successfully compile this.. Stop. You may of course write more complex tests if you need. Anything that you can do with a shell script, you can do it with a Makefile. That said, I personally prefer to fail compilation due to missing header files. It's simpler, and there's not much difference. After all, if compilation fails for <foo.h>, it's trivial to run $ apt-file find /include/foo.h But if you want the test, you can have it. Have a lovely day! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-29 8:42 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar @ 2026-08-29 8:45 ` Alejandro Colomar 2026-08-29 8:52 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 8:45 UTC (permalink / raw) To: Larry Kollar; +Cc: Groff, linux-man [-- Attachment #1: Type: text/plain, Size: 2235 bytes --] > Date: 2026-08-29 10:42:14+0200 > From: Alejandro Colomar <alx@kernel.org> > > Hi Larry, > > > Date: 2026-08-28 22:50:50-0400 > > From: Larry Kollar <larry.kollar@icloud.com> > > > > > > Alejandro Colomar <alx@kernel.org> wrote: > > > > > I believe that a set of makefiles that would handle all of the targets > > > of a project like groff wouldn't take much more than that. It might be > > > a few hundred kB. If it's well organized, it can be maintainable. > > > > > > Because the makefile language is so simple, bugs are easy to spot and > > > fix, compared to autotools (possibly automake, but I can't distinguish > > > them enough). > > > > I don’t know. Can a Makefile check for the presence of certain libraries > > or other apps and fail gracefully (by which I mean exiting with a message > > like “You need app X, plus libraries Y and Z, installed to successfully > > compile this.”)? That’s one of the things that “makes" me appreciate taking > > that extra step of typing `.configure` before make. > > Yes, it can. Here's a trivial test for that: > > alx@devuan:~/tmp/testlib$ cat Makefile > HAS_LIBFOO := $(shell find /usr/include/foo.h >/dev/null && echo yes || echo no) > > ifeq ($(HAS_LIBFOO),no) > $(error You need library FOO installed to successfully compile this.) Oh, I didn't need the period here... > endif > > all: > echo Done > alx@devuan:~/tmp/testlib$ make > find: ‘/usr/include/foo.h’: No such file or directory > Makefile:4: *** You need library FOO installed to successfully compile this.. Stop. ... make(1) already appended one here. :) > > You may of course write more complex tests if you need. Anything that > you can do with a shell script, you can do it with a Makefile. > > That said, I personally prefer to fail compilation due to missing header > files. It's simpler, and there's not much difference. After all, if > compilation fails for <foo.h>, it's trivial to run > > $ apt-file find /include/foo.h > > But if you want the test, you can have it. > > > Have a lovely day! > Alex > > -- > <https://www.alejandro-colomar.es> -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-29 8:45 ` Alejandro Colomar @ 2026-08-29 8:52 ` Alejandro Colomar 2026-08-29 9:02 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 8:52 UTC (permalink / raw) To: Larry Kollar; +Cc: Groff, linux-man [-- Attachment #1: Type: text/plain, Size: 2752 bytes --] > Date: 2026-08-29 10:45:34+0200 > From: Alejandro Colomar <alx@kernel.org> > > > Date: 2026-08-29 10:42:14+0200 > > From: Alejandro Colomar <alx@kernel.org> > > > > Hi Larry, > > > > > Date: 2026-08-28 22:50:50-0400 > > > From: Larry Kollar <larry.kollar@icloud.com> > > > > > > > > > Alejandro Colomar <alx@kernel.org> wrote: > > > > > > > I believe that a set of makefiles that would handle all of the targets > > > > of a project like groff wouldn't take much more than that. It might be > > > > a few hundred kB. If it's well organized, it can be maintainable. > > > > > > > > Because the makefile language is so simple, bugs are easy to spot and > > > > fix, compared to autotools (possibly automake, but I can't distinguish > > > > them enough). > > > > > > I don’t know. Can a Makefile check for the presence of certain libraries > > > or other apps and fail gracefully (by which I mean exiting with a message > > > like “You need app X, plus libraries Y and Z, installed to successfully > > > compile this.”)? That’s one of the things that “makes" me appreciate taking > > > that extra step of typing `.configure` before make. > > > > Yes, it can. Here's a trivial test for that: > > > > alx@devuan:~/tmp/testlib$ cat Makefile > > HAS_LIBFOO := $(shell find /usr/include/foo.h >/dev/null && echo yes || echo no) You can also trivially test with gcc(1) instead of find(1): $ echo '#include <foo.h>' | gcc -x c -E >/dev/null 2>&1 && echo yes || echo no no If you put that expression within $(shell ...), you can use it similarly. Cheers, alex > > > > ifeq ($(HAS_LIBFOO),no) > > $(error You need library FOO installed to successfully compile this.) > > Oh, I didn't need the period here... > > > endif > > > > all: > > echo Done > > alx@devuan:~/tmp/testlib$ make > > find: ‘/usr/include/foo.h’: No such file or directory > > Makefile:4: *** You need library FOO installed to successfully compile this.. Stop. > > ... make(1) already appended one here. > > :) > > > > > You may of course write more complex tests if you need. Anything that > > you can do with a shell script, you can do it with a Makefile. > > > > That said, I personally prefer to fail compilation due to missing header > > files. It's simpler, and there's not much difference. After all, if > > compilation fails for <foo.h>, it's trivial to run > > > > $ apt-file find /include/foo.h > > > > But if you want the test, you can have it. > > > > > > Have a lovely day! > > Alex > > > > -- > > <https://www.alejandro-colomar.es> > > > > -- > <https://www.alejandro-colomar.es> -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) 2026-08-29 8:52 ` Alejandro Colomar @ 2026-08-29 9:02 ` Alejandro Colomar 0 siblings, 0 replies; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 9:02 UTC (permalink / raw) To: Larry Kollar; +Cc: Groff, linux-man [-- Attachment #1: Type: text/plain, Size: 3938 bytes --] > Date: 2026-08-29 10:53:02+0200 > From: Alejandro Colomar <alx@kernel.org> > > > Date: 2026-08-29 10:45:34+0200 > > From: Alejandro Colomar <alx@kernel.org> > > > > > Date: 2026-08-29 10:42:14+0200 > > > From: Alejandro Colomar <alx@kernel.org> > > > > > > Hi Larry, > > > > > > > Date: 2026-08-28 22:50:50-0400 > > > > From: Larry Kollar <larry.kollar@icloud.com> > > > > > > > > > > > > Alejandro Colomar <alx@kernel.org> wrote: > > > > > > > > > I believe that a set of makefiles that would handle all of the targets > > > > > of a project like groff wouldn't take much more than that. It might be > > > > > a few hundred kB. If it's well organized, it can be maintainable. > > > > > > > > > > Because the makefile language is so simple, bugs are easy to spot and > > > > > fix, compared to autotools (possibly automake, but I can't distinguish > > > > > them enough). > > > > > > > > I don’t know. Can a Makefile check for the presence of certain libraries > > > > or other apps and fail gracefully (by which I mean exiting with a message > > > > like “You need app X, plus libraries Y and Z, installed to successfully > > > > compile this.”)? That’s one of the things that “makes" me appreciate taking > > > > that extra step of typing `.configure` before make. > > > > > > Yes, it can. Here's a trivial test for that: > > > > > > alx@devuan:~/tmp/testlib$ cat Makefile > > > HAS_LIBFOO := $(shell find /usr/include/foo.h >/dev/null && echo yes || echo no) > > You can also trivially test with gcc(1) instead of find(1): > > $ echo '#include <foo.h>' | gcc -x c -E >/dev/null 2>&1 && echo yes || echo no > no > > If you put that expression within $(shell ...), you can use it similarly. Of course, I had some typos there. Here's a fully working example: alx@devuan:~/tmp/testlib$ cat Makefile CC ::= cc HAS_STDLIB ::= \ $(shell \ echo '#include <stdlib.h>' \ | $(CC) -x c - -E >/dev/null \ && echo yes \ || echo no; \ ) HAS_LIBFOO ::= \ $(shell \ echo '#include <foo.h>' \ | $(CC) -x c - -E >/dev/null \ && echo yes \ || echo no; \ ) ifeq ($(HAS_STDLIB),no) $(error You need <stdlib.h> installed to successfully compile this) endif ifeq ($(HAS_LIBFOO),no) $(error You need library FOO installed to successfully compile this) endif all: echo Done alx@devuan:~/tmp/testlib$ make <stdin>:1:10: fatal error: foo.h: No such file or directory compilation terminated. Makefile:23: *** You need library FOO installed to successfully compile this. Stop. Cheers, Alex > > > Cheers, > alex > > > > > > > ifeq ($(HAS_LIBFOO),no) > > > $(error You need library FOO installed to successfully compile this.) > > > > Oh, I didn't need the period here... > > > > > endif > > > > > > all: > > > echo Done > > > alx@devuan:~/tmp/testlib$ make > > > find: ‘/usr/include/foo.h’: No such file or directory > > > Makefile:4: *** You need library FOO installed to successfully compile this.. Stop. > > > > ... make(1) already appended one here. > > > > :) > > > > > > > > You may of course write more complex tests if you need. Anything that > > > you can do with a shell script, you can do it with a Makefile. > > > > > > That said, I personally prefer to fail compilation due to missing header > > > files. It's simpler, and there's not much difference. After all, if > > > compilation fails for <foo.h>, it's trivial to run > > > > > > $ apt-file find /include/foo.h > > > > > > But if you want the test, you can have it. > > > > > > > > > Have a lovely day! > > > Alex > > > > > > -- > > > <https://www.alejandro-colomar.es> > > > > > > > > -- > > <https://www.alejandro-colomar.es> > > > > -- > <https://www.alejandro-colomar.es> -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) [not found] ` <8DE76435-CBDB-42D6-9E0F-9E27291560B6@icloud.com> 2026-08-29 8:42 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar @ 2026-08-29 9:39 ` Ingo Schwarze 2026-08-29 13:10 ` configure separate from make or not (was: Using LS/LE) Alejandro Colomar 1 sibling, 1 reply; 41+ messages in thread From: Ingo Schwarze @ 2026-08-29 9:39 UTC (permalink / raw) To: Larry Kollar; +Cc: Alejandro Colomar, Groff, linux-man Hi Larry, Larry Kollar wrote on Fri, Aug 28, 2026 at 10:50:50PM -0400: > Alejandro Colomar <alx@kernel.org> wrote: >> I believe that a set of makefiles that would handle all of the targets >> of a project like groff wouldn't take much more than that. It might be >> a few hundred kB. If it's well organized, it can be maintainable. >> >> Because the makefile language is so simple, bugs are easy to spot and >> fix, compared to autotools (possibly automake, but I can't distinguish >> them enough). > I don't know. Can a Makefile check for the presence of certain libraries > or other apps and fail gracefully Obviously, a Makefile can do anything a sh(1) script can do - arguably, the central idea of make(1) is topological sorting of sh(1) script snippets according to a dependency graph. So the answer to your question is an emphatic "yes". > (by which I mean exiting with a message like "You need app X, plus > libraries Y and Z, installed to successfully compile this.")? Absolutely, and some real-world Makefiles do just that, for example the large and frightening bsd.port.mk(5) on OpenBSD: https://man.openbsd.org/bsd.port.mk https://cvsweb.openbsd.org/ports/infrastructure/mk/bsd.port.mk But smaller, simpler Makefiles emitting diagnostic messages of the kind you describe exist, too. > That's one of the things that "makes" me appreciate taking > that extra step of typing `.configure` before make. Well, that doesn't look like a particularly strong argument, because adding a rule to the Makefile that automatically runs the configure script when needed would usually not be difficult, and the end result regarding diagnostics would be identical to what you desire. I think the main reason why build system developers don't usually run configure automatically from the Makefile is that from a user perspective, it makes sense to keep the two steps "inspect the configuration and make some decisions, but do not start building anything just yet" and "build the stuff, using the variables and decisions made at the configure stage" separate. Users may even want to pause between the two steps, consider the decisions made, for example by inspecting configure output files like config.h or Makefile.local or, in case serious debugging is needed, config.log and maybe even change some of the decisions manually and re-run configure, even though autoconf(1) makes both steps, inspection and manipulation of decisions, gratuitiously hard, both by spewing vast amounts of noise and by the ./configure script being next to unreadable. But saner, better-written configure scripts can make both inspection and manipulation quite simple and pleasant. Running the configure script automatically from the Makefile would remove this opportunity for inspection and tweaking. My point isn't that configure should be integrated into the Makefile. Quite to the contrary, medium-sized projects like groff and mandoc that need to run dozens of configuration tests do benefit from having a separate configure script. What i'm saying is that developers can save themselves massive amounts of work and pain by ditching autoconf(1) and writing their own configure script - and thus also make life massively easier for their users, because dealing with autoconf(1) is equally painful for users. But again, i do *not* advocate for ripping autoconf(1) out of groff because Branden seems happy enough with it for now, and it kind of works most of time, admittedly with regular hiccups around releases. Ripping it out would look like a make-work project at this point; constantly revisiting the same decisions is not very productive, and automake(1) was only integrated a few years ago. > Now, a lot of older software (or modern, simple programs) won't > need that complexity, and a well-written INSTALL file can call out > necessary Makefile edits before letting 'er rip. Right, suckless.org software comes to mind as an example. (That's not to say that i would endorse them in every respect - for example, i like small amounts of configurability and do not like the "zero configuration at run time" approach of suckless.) Yours, Ingo ^ permalink raw reply [flat|nested] 41+ messages in thread
* configure separate from make or not (was: Using LS/LE) 2026-08-29 9:39 ` Ingo Schwarze @ 2026-08-29 13:10 ` Alejandro Colomar 2026-08-29 15:31 ` configure separate from make or not Ingo Schwarze 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 13:10 UTC (permalink / raw) To: Ingo Schwarze; +Cc: Larry Kollar, Groff, linux-man [-- Attachment #1: Type: text/plain, Size: 2398 bytes --] Hi Ingo, > Date: 2026-08-29 11:39:20+0200 > From: Ingo Schwarze <schwarze@usta.de> > [...] > > I think the main reason why build system developers don't usually > run configure automatically from the Makefile is that from a user > perspective, it makes sense to keep the two steps "inspect the > configuration and make some decisions, but do not start building > anything just yet" and "build the stuff, using the variables and > decisions made at the configure stage" separate. Users may even > want to pause between the two steps, consider the decisions made, > for example by inspecting configure output files like config.h > or Makefile.local or, in case serious debugging is needed, config.log > and maybe even change some of the decisions manually and re-run > configure, even though autoconf(1) makes both steps, inspection > and manipulation of decisions, gratuitiously hard, both by spewing > vast amounts of noise and by the ./configure script being next to > unreadable. But saner, better-written configure scripts can make > both inspection and manipulation quite simple and pleasant. > > Running the configure script automatically from the Makefile > would remove this opportunity for inspection and tweaking. In the Linux man-pages, the configure step is done entirely within make(1) --there's no separate ./configure step--. But as you say, a separate configure-only step is important for serious debugging. The solution I implemented is a 'nothing' target in the Makefile, which as the name implies, does nothing. However, it still runs the configuration step, since that runs as part of parsing the makefiles. Here's the rule: nothing:; When I need to debug the build system itself, I run that target; often with special flags for debugging. One common command I use when I need to do this kind of debugging is: $ make -p nothing | less And if I need to see stderr output from the commands used by the configure scripts, here's a common command: $ make HIDE_ERR= nothing I'm not saying that this should be done, but this _can_ be done. With BSD make(1), it might be more difficult to debug, since it doesn't have the -p flag. But the output from configure tests can still be read without building anything, with a dummy 'nothing' rule. Have a lovely day! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: configure separate from make or not 2026-08-29 13:10 ` configure separate from make or not (was: Using LS/LE) Alejandro Colomar @ 2026-08-29 15:31 ` Ingo Schwarze 2026-08-29 20:49 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: Ingo Schwarze @ 2026-08-29 15:31 UTC (permalink / raw) To: Alejandro Colomar; +Cc: linux-man [trimming Cc:, this starts becoming off-topic on the groff list; i'm not subscribed to linux-man@ though] Hi Alejandro, Alejandro Colomar wrote on Sat, Aug 29, 2026 at 03:10:25PM +0200: > From: Ingo Schwarze <schwarze@usta.de> > In the Linux man-pages, the configure step is done entirely within > make(1) --there's no separate ./configure step--. But as you say, > a separate configure-only step is important for serious debugging. > > The solution I implemented is a 'nothing' target in the Makefile, which > as the name implies, does nothing. However, it still runs the > configuration step, since that runs as part of parsing the makefiles. That sounds like a serious abuse of the parsing step to me. I mean, the whole point of a parsing step is to do parsing and to build dependency trees, but not to run code. The purpose of the execution phase of make(1) then is to run code, in an order determined from the dependency tree. > Here's the rule: > > nothing:; > > When I need to debug the build system itself, I run that target; often > with special flags for debugging. One common command I use when I need > to do this kind of debugging is: > > $ make -p nothing | less The output of that command looks completely unreadable to me and is of horrendous size: $ gmake -pR nothing | wc bash: line 1: gcc: command not found realpath: unknown option -- m usage: realpath [-q] file gmake: warning: undefined variable 'GNUMAKEFLAGS' 34074 672611 27635924 Over 25 MB of configuration output? Seriously? > And if I need to see stderr output from the commands used by the > configure scripts, here's a common command: > > $ make HIDE_ERR= nothing > > I'm not saying that this should be done, but this _can_ be done. With > BSD make(1), it might be more difficult to debug, since it doesn't have > the -p flag. It does. From the OpenBSD make(1) manual: -p Print a dump of the target rules and variables on stdout. Do not build anything. -d flags Turn on debugging, and specify which portions of make are to print debugging information. flags is one or more of the following: [only quoting the flags here, without the descriptions, for brevity] AacdDef g1 g2 hiklmnpqstTv However, reading the output from a simple configure script is much simpler than reading make(1) debugging output, for example: $ ./configure file config.log: writing... file configure.local: reading... tested operating system: OpenBSD -> OSENUM=MANDOC_OS_OPENBSD tested cc -W: tested noop: yes selected CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings -Wno-unused-parameter" tested noop-static: yes selected STATIC="-static" tested attribute: yes tested cmsg: yes tested dirent-namlen: yes tested be32toh: yes tested be32toh-DSYS_ENDIAN: yes tested EFTYPE: yes tested err: yes tested getline: yes tested getsubopt: yes tested isblank: yes tested mkdtemp: yes tested mkstemps: yes tested nanosleep: yes tested ntohl: yes tested O_DIRECTORY: yes tested PATH_MAX: yes tested pledge: yes tested sandbox_init: no (compilation failed) tested progname: yes tested reallocarray: yes tested recallocarray: yes tested recvmsg: yes tested rewb-bsd: yes tested rewb-sysv: yes tested strcasestr: yes tested stringlist: no (compilation failed) tested strlcat: yes tested strlcpy: yes tested strndup: yes tested strptime: yes tested strsep: yes tested strtonum: yes tested unveil: yes tested vasprintf: yes tested fts-DFTS_COMPARE_CONST: no (compilation failed) tested fts: yes tested less: yes selected BINM_PAGER=less tested less -T: yes selected UTF8_LOCALE=en_US.UTF-8 tested wchar-DUTF8_LOCALE="en_US.UTF-8": yes tested ohash: no (compilation failed) tested ohash-lutil: yes selected LDADD=" -lutil -lz" file config.h: written file Makefile.local: written and then you can inspect config.h and Makefile.local for generated settings and inspect config.log if serious debugging is needed. $ wc config.h Makefile.local config.log 54 150 1326 config.h 40 137 1026 Makefile.local 305 1401 12998 config.log 399 1688 15350 total Even the "total" is half a permille of the output volume from the gmake -p you recommend - and that already includes *all* the debugging information, whereas in your 25 MB of gmake -p output, i was unable to find the reason why the build systems tries to use gcc(1) even though i don't have GCC installed. Generally, searching in that monster is next to impossble because it contains very large numbers of extremely long lines, each of which contains basically all the words that one might possibly wish to search for. > But the output from configure tests can still be read > without building anything, with a dummy 'nothing' rule. I briefly tried to read man-pages/GNUmakefile but quickly gave up because it feels impossible to follow the control flow. The program fails to explicitly say which targets it runs with which dependencies, IMHO making it unreadable for a human. Yours, Ingo ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: configure separate from make or not 2026-08-29 15:31 ` configure separate from make or not Ingo Schwarze @ 2026-08-29 20:49 ` Alejandro Colomar 2026-08-30 13:17 ` Alejandro Colomar 0 siblings, 1 reply; 41+ messages in thread From: Alejandro Colomar @ 2026-08-29 20:49 UTC (permalink / raw) To: Ingo Schwarze; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 14275 bytes --] Hi Ingo, > Date: 2026-08-29 17:31:32+0200 > From: Ingo Schwarze <schwarze@usta.de> > > [trimming Cc:, this starts becoming off-topic on the groff list; > i'm not subscribed to linux-man@ though] > > Hi Alejandro, > > Alejandro Colomar wrote on Sat, Aug 29, 2026 at 03:10:25PM +0200: > > From: Ingo Schwarze <schwarze@usta.de> > > > In the Linux man-pages, the configure step is done entirely within > > make(1) --there's no separate ./configure step--. But as you say, > > a separate configure-only step is important for serious debugging. > > > > The solution I implemented is a 'nothing' target in the Makefile, which > > as the name implies, does nothing. However, it still runs the > > configuration step, since that runs as part of parsing the makefiles. > > That sounds like a serious abuse of the parsing step to me. > I mean, the whole point of a parsing step is to do parsing and to > build dependency trees, but not to run code. The main thing I run code for in the makefiles is for listing all the source files. Here's an example: $ grepc -xmk -tv -n MANPAGES share/mk/ share/mk/src/man.mk:20:MANPAGES ::= $(shell $(FIND) $(MANDIR)/* -type f \ | $(GREP) -E '$(MANEXT)' \ | $(SORTMAN) \ | $(SED) 's,:,\\:,g') I know you prefer to list them manually, but I like this little bit of magic (it's not that magic, since it's written in the code, but admittedly, if you're not used to this build system, it's hard to expect it). > The purpose of the > execution phase of make(1) then is to run code, in an order determined > from the dependency tree. > > > Here's the rule: > > > > nothing:; > > > > When I need to debug the build system itself, I run that target; often > > with special flags for debugging. One common command I use when I need > > to do this kind of debugging is: > > > > $ make -p nothing | less > > The output of that command looks completely unreadable to me and > is of horrendous size: > > $ gmake -pR nothing | wc > bash: line 1: gcc: command not found > realpath: unknown option -- m > usage: realpath [-q] file > gmake: warning: undefined variable 'GNUMAKEFLAGS' > 34074 672611 27635924 > > Over 25 MB of configuration output? Seriously? Hmmm, I would like it to be less. I've been thinking about ideas to cut it down a little bit (at least one order of magnitude). The thing is, we have 1.5k non-link pages, and we use absolute paths in most variables. Thus, each variable can hold around 100kB for the paths: $ find man/ -type f | xargs grep -l '^\.TH' | xargs realpath | wc -c 106833 'make help-list-targets' lists 119 .PHONY targets, of which most require at least one variable for holding the actual file targets. A simple multiplication and rounding says there's 100x100k = 10M in these path variables. Then 25 MB sounds not far from that. I think I might be able to optimize this down by using relative paths. I might be able to optimize this a bit further by using suffix rules as much as possible, instead of listing all targets in the rules again. But there's a hard floor. It should be hard to go much below current size, at least without reducing targets. I tried removing some targets, out of curiosity, to see how much size they contribute: $ rm -rf share/mk/lint/ $ rm -rf share/mk/check/ $ rm -rf share/mk/build/examples/ $ rm -rf share/mk/build/catman/ $ rm -rf share/mk/build/fonts/ $ rm -rf share/mk/build/html/ $ rm -rf share/mk/build/pdf/ $ rm -rf share/mk/build/ps/ $ rm -rf share/mk/build/pre/ $ rm -rf share/mk/dist/check/ $ rm -rf share/mk/install/html.mk $ rm -rf share/mk/install/pdf/ After that, the output of 'make -p nothing' goes down to ~ 1/7.5 of the original size. This is still sufficient to build and install the pages, and produce the release tarball. The rest is for detecting issues in the pages, the examples, and in the tarball. The main issue is the large number of files, not the complexity of what we do with them. With thousands of pages, the size must remain in MB, or in the high kB. > > And if I need to see stderr output from the commands used by the > > configure scripts, here's a common command: > > > > $ make HIDE_ERR= nothing > > > > I'm not saying that this should be done, but this _can_ be done. With > > BSD make(1), it might be more difficult to debug, since it doesn't have > > the -p flag. > > It does. From the OpenBSD make(1) manual: > > -p Print a dump of the target rules and variables on stdout. Do not > build anything. Oh, I didn't remember each BSD has its own make(1). I checked bmake(1), which is available in Debian and doesn't have -p, but that seems to be NetBSD's make(1). > > -d flags > Turn on debugging, and specify which portions of make are to > print debugging information. flags is one or more of the > following: > > [only quoting the flags here, without the descriptions, > for brevity] > > AacdDef g1 g2 hiklmnpqstTv > > However, reading the output from a simple configure script is much > simpler than reading make(1) debugging output, for example: > > $ ./configure > file config.log: writing... > file configure.local: reading... > tested operating system: OpenBSD -> OSENUM=MANDOC_OS_OPENBSD > tested cc -W: tested noop: yes > selected CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings -Wno-unused-parameter" > tested noop-static: yes > selected STATIC="-static" > tested attribute: yes > tested cmsg: yes You could implement this output in a makefile, and it would take as much code as it takes in a configure script. You may not like having code that runs before targets (and that's reasonable, of course), but it also has benefits: having an atomic configure+make operation, avoids issues due to outdated configure output; I don't need to 'make clean' anymore, for example. [...] > and then you can inspect config.h and Makefile.local for generated > settings and inspect config.log if serious debugging is needed. > > $ wc config.h Makefile.local config.log > 54 150 1326 config.h > 40 137 1026 Makefile.local > 305 1401 12998 config.log > 399 1688 15350 total > > Even the "total" is half a permille of the output volume > from the gmake -p you recommend - and that already includes *all* I don't _recommend_ it. I just mentioned it as a possibility. I mentioned it since you had said it was impossible to do it, IIRC. > the debugging information, whereas in your 25 MB of gmake -p output, > i was unable to find the reason why the build systems tries to use gcc(1) > even though i don't have GCC installed. Generally, searching in that > monster is next to impossble because it contains very large numbers > of extremely long lines, each of which contains basically all the > words that one might possibly wish to search for. Many lines have it, as there's a directory called .../gcc/, but with a regex we can get rid of it and show just a bunch of lines: $ make -R nothing -p | grep '[^/]gcc' make: warning: undefined variable 'GNUMAKEFLAGS' CC_VENDOR := gcc CPP := gcc -O3 -flto -Wall -Wextra -Werror -Wstrict-prototypes -Wdeclaration-after-statement -Wno-reserved-identifier -Wno-unused-macros -Wno-error=unused-parameter -Wno-error=sign-compare -Wno-error=format -Wno-error=uninitialized -fanalyzer -E LD := gcc -O3 -flto -Wall -Wextra -Werror -Wstrict-prototypes -Wdeclaration-after-statement -Wno-reserved-identifier -Wno-unused-macros -Wno-error=unused-parameter -Wno-error=sign-compare -Wno-error=format -Wno-error=uninitialized -fanalyzer -isystem /usr/include/x86_64-linux-gnu/bsd -DLIBBSD_OVERLAY -D_FORTIFY_SOURCE=2 CC := gcc CC_VENDOR and/or CC sound suspicious. Both seem to be defined in the same file: $ grepc -xmk -tv CC_VENDOR share/mk/ share/mk/configure/build-depends/gcc/cc.mk:CC_VENDOR ::= \ $(shell \ $(CC) -v 2>&1 \ | $(SED) -n '1p;$$p' \ | $(SED) '/gcc version/s/.*/gcc/' \ | $(SED) '/clang version/s/.*/clang/' \ | $(SED) '/Apple LLVM version/s/.*/clang/' \ | $(GREP) -e '^gcc$$' -e '^clang$$' \ || $(ECHO) unknown; \ ) $ grepc -xmk -tv CC share/mk/ share/mk/configure/build-depends/gcc/cc.mk:CC ::= gcc And so it seems it's CC. I don't know why I set it to gcc. I'll fix it, and set it to just 'cc'. Thanks for the report! It seems CC was previously set as cc, and in 546141e11357 (2024-02-17; "share/mk/: Reorganize build dependencies") I changed it to gcc, but that seems an accident. I've applied this fix: commit 294f74eb2a284ecf8772cb0060b85b6d3f9bb7bd Author: Alejandro Colomar <alx@kernel.org> Date: 2026-08-29 21:42:58 +0200 share/mk/: $CC: Use cc(1), not gcc(1) Fixes: 546141e11357 (2024-02-17; "share/mk/: Reorganize build dependencies") Reported-by: Ingo Schwarze <schwarze@openbsd.org> Message-ID: <apL7VAruk1bIOr1M@isnote.usta.de> Signed-off-by: Alejandro Colomar <alx@kernel.org> diff --git a/share/mk/configure/build-depends/gcc/cc.mk b/share/mk/configure/build-depends/gcc/cc.mk index 80c07b4f4a09..d541e39137a0 100644 --- a/share/mk/configure/build-depends/gcc/cc.mk +++ b/share/mk/configure/build-depends/gcc/cc.mk @@ -12,7 +12,7 @@ include $(MAKEFILEDIR)/configure/build-depends/sed/sed.mk ifndef CC -CC ::= gcc +CC ::= cc endif > > But the output from configure tests can still be read > > without building anything, with a dummy 'nothing' rule. > > I briefly tried to read man-pages/GNUmakefile but quickly gave up > because it feels impossible to follow the control flow. > The program fails to explicitly say which targets it runs > with which dependencies, IMHO making it unreadable for a human. The start point is, as usual, the 'all' target, whose rule is defined as this: all: build; It has an empty recipe, and depends on the 'build' target. The 'build' target is defined under share/mk/: $ grepc -xmk -tr -n build share/mk/ share/mk/build/_.mk:25:build: \ build-man; $ grepc -xmk -tr -n build-man share/mk/ share/mk/build/man/_.mk:18:build-man: build-man-nonso build-man-so; $ grepc -xmk -tr -n build-man-nonso share/mk/ share/mk/build/man/nonso.mk:32:build-man-nonso: $(_NONSO) $ grepc -xmk -tr -n build-man-so share/mk/ share/mk/build/man/so.mk:24:build-man-so: $(_SO_MAN) Those are all empty recipes, since they're .PHONY targets. The real targets are $(_NONSO) and $(_SO_MAN). $ grepc -xmk -tr -n _NONSO share/mk/ share/mk/build/man/nonso.mk:18:_NONSO ::= $(patsubst $(MANDIR)/%, $(_MANDIR)/%, $(NONSO)) share/mk/build/man/nonso.mk:21:$(_NONSO): $(_MANDIR)/%: $(MANDIR)/% $(MK) | $$(@D)/ $(info $(INFO_)SED $@) <$< \ $(SED) "/^\.TH /s/(date)/$$($(MANPAGEDATECMD))/" \ | $(SED) '/^\.TH /s/(unreleased)/$(DISTVERSION)/' \ | $(SED) '/^\.Dd /s/$$Mdocdate$$'"/$$($(MANPAGEDATECMD))/" \ | $(SED) '/^\.Os /s/(unreleased)/$(DISTVERSION)/' \ >$@ $ grepc -xmk -tr -n _SO_MAN share/mk/ share/mk/build/man/so.mk:15:_SO_MAN ::= $(patsubst $(MANDIR)/%, $(_MANDIR)/%, $(SO_MAN)) share/mk/build/man/so.mk:18:$(_SO_MAN): $(_MANDIR)/%: $(MANDIR)/% $(MK) | $$(@D)/ $(info $(INFO_)CP $@) $(CP) -T $< $@ The latter copies .so pages as is, while the former takes the non-link pages and edits the date and version, with values gotten from git(1). We can also follow that: $ grepc -xmk -tv -n MANPAGEDATECMD share/mk/ share/mk/configure/version.mk:62:MANPAGEDATECMD = $(GIT) log --format=%cs -1 -- $< $(HIDE_ERR) $ grepc -xmk -tv -n VERSION share/mk/ share/mk/configure/version.mk:23:VERSION ::= $(shell $(GIT) describe --dirty | $(SED) 's/$(projname)-//') That's all that runs through the 'all' target. Then there's stuff that runs prior to it, for initializing some variables, but that should not produce any lasting effects, so it should be more or less unimportant (unless you want to debug stuff, and then you need to see the output of -p to learn it). You can check everything that runs before any targets, by grepping for '$(shell ' under share/mk/: $ grep -rn '$(shell ' share/mk/ share/mk/src/man.mk:20:MANPAGES ::= $(shell $(FIND) $(MANDIR)/* -type f \ share/mk/src/man.mk:26:MANINTROPAGES ::= $(shell $(FIND) $(MANDIR)/* -type f \ share/mk/src/man.mk:45:NONSO ::= $(shell $(FIND) $(MANDIR)/* -type f \ share/mk/src/sh.mk:16:BIN_sh ::= $(shell $(FIND) $(SRCBINDIR) -type f \ share/mk/dist/files.mk:21:DISTFILES ::= $(shell $(DISTFILESCMD) | $(SED) 's,:,\\:,g') share/mk/dist/files.mk:29: $(shell \ share/mk/configure/version.mk:23:VERSION ::= $(shell $(GIT) describe --dirty | $(SED) 's/$(projname)-//') share/mk/configure/version.mk:58:DISTDATE ::= $(shell $(DISTDATECMD)) share/mk/configure/build-depends/cpp/cpp.mk:22: $(shell \ share/mk/configure/build-depends/cpp/cpp.mk:31: $(shell $(PKGCONF_CMD) --cflags $(PKGCONF_LIBS) $(HIDE_ERR)) share/mk/configure/build-depends/groff-base/nroff.mk:20:NROFF_LINE_LENGTH ::= $(shell $(EXPR) $(MANWIDTH) - 2) share/mk/configure/build-depends/groff-base/nroff.mk:24: $(shell $(LOCALE) charmap \ share/mk/configure/build-depends/binutils/ld.mk:22: $(shell \ share/mk/configure/build-depends/binutils/ld.mk:35: $(shell $(PKGCONF_CMD) --libs-only-L $(PKGCONF_LIBS) $(HIDE_ERR)) \ share/mk/configure/build-depends/binutils/ld.mk:36: $(shell $(PKGCONF_CMD) --libs-only-other $(PKGCONF_LIBS) $(HIDE_ERR)) share/mk/configure/build-depends/binutils/ld.mk:52: $(shell $(PKGCONF_CMD) --libs-only-l $(PKGCONF_LIBS) $(HIDE_ERR)) share/mk/configure/build-depends/gcc/cc.mk:20: $(shell \ The order in which these run is unspecified (there are obvious dependencies, if one variable uses the results of another, though), but if you're interested in auditing everything that may run with 'make nothing' (and thus with every run of make(1), with any targets), this would be the list. Have a lovely night! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: configure separate from make or not 2026-08-29 20:49 ` Alejandro Colomar @ 2026-08-30 13:17 ` Alejandro Colomar 0 siblings, 0 replies; 41+ messages in thread From: Alejandro Colomar @ 2026-08-30 13:17 UTC (permalink / raw) To: Ingo Schwarze; +Cc: linux-man [-- Attachment #1: Type: text/plain, Size: 2479 bytes --] Hi Ingo, > Date: 2026-08-29 22:49:08+0200 > From: Alejandro Colomar <alx@kernel.org> > [...] > > The main thing I run code for in the makefiles is for listing all the > source files. Here's an example: > > $ grepc -xmk -tv -n MANPAGES share/mk/ > share/mk/src/man.mk:20:MANPAGES ::= $(shell $(FIND) $(MANDIR)/* -type f \ > | $(GREP) -E '$(MANEXT)' \ > | $(SORTMAN) \ > | $(SED) 's,:,\\:,g') > > I know you prefer to list them manually, but I like this little bit > of magic (it's not that magic, since it's written in the code, but > admittedly, if you're not used to this build system, it's hard to > expect it). BTW, the git repository is tracking 3387 files (at the moment, and growing), and thus the distribution tarball contains that many files. Given this amount of files, I find it more maintainable using scripts instead of hard-coded lists. I could have a hard-coded list, and regularly diff it with the output of find(1), but I prefer using find(1) directly in the makefiles. Also, I wouldn't want to have 80k of Makefile text that is the output of a command: $ git ls-files | wc -c 80511 We already have quite heavy makefiles, at around 100k, and that would duplicate their size. [...] > The thing is, we have 1.5k non-link pages, and we use absolute paths > in most variables. Thus, each variable can hold around 100kB for the > paths: > > $ find man/ -type f | xargs grep -l '^\.TH' | xargs realpath | wc -c > 106833 > > 'make help-list-targets' lists 119 .PHONY targets, of which most require > at least one variable for holding the actual file targets. A simple > multiplication and rounding says there's 100x100k = 10M in these path > variables. Then 25 MB sounds not far from that. > > I think I might be able to optimize this down by using relative paths. > I might be able to optimize this a bit further by using suffix rules > as much as possible, instead of listing all targets in the rules again. > But there's a hard floor. It should be hard to go much below current > size, at least without reducing targets. Self-correction: we're not using absolute paths; they're relative. It seems I had already implemented this optimization, and I didn't remember. Anyway, relative paths don't change much. The best gain would come from using suffix rules, which would save a few variables entirely. Have a lovely day! Alex -- <https://www.alejandro-colomar.es> [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2026-08-30 13:17 UTC | newest]
Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-03 19:21 [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config DJ Delorie
2026-08-06 14:37 ` Alejandro Colomar
2026-08-06 15:33 ` DJ Delorie
2026-08-06 19:14 ` Alejandro Colomar
2026-08-06 20:17 ` DJ Delorie
2026-08-06 20:31 ` Alejandro Colomar
2026-08-06 20:42 ` DJ Delorie
2026-08-07 2:12 ` G. Branden Robinson
2026-08-07 3:29 ` DJ Delorie
2026-08-07 3:49 ` G. Branden Robinson
2026-08-07 4:01 ` DJ Delorie
2026-08-07 4:09 ` G. Branden Robinson
2026-08-23 12:29 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar
2026-08-23 13:27 ` G. Branden Robinson
2026-08-23 13:55 ` Alejandro Colomar
2026-08-23 14:16 ` G. Branden Robinson
2026-08-23 15:06 ` Alejandro Colomar
2026-08-23 16:44 ` G. Branden Robinson
2026-08-23 19:30 ` Alejandro Colomar
2026-08-23 20:40 ` G. Branden Robinson
2026-08-23 23:11 ` Alejandro Colomar
2026-08-24 1:11 ` G. Branden Robinson
2026-08-24 2:01 ` Using LS/LE Collin Funk
2026-08-24 11:08 ` Alejandro Colomar
2026-08-24 11:00 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar
2026-08-23 22:31 ` autotools, was: Using LS/LE Ingo Schwarze
2026-08-24 0:09 ` Alejandro Colomar
2026-08-29 4:36 ` G. Branden Robinson
2026-08-29 11:34 ` Ingo Schwarze
2026-08-29 12:51 ` Alejandro Colomar
2026-08-29 19:16 ` G. Branden Robinson
2026-08-29 21:43 ` Alejandro Colomar
[not found] ` <8DE76435-CBDB-42D6-9E0F-9E27291560B6@icloud.com>
2026-08-29 8:42 ` Using LS/LE (was: [PATCH v4 2/4] man/man5/tunables.conf: Document system-wide tunables config) Alejandro Colomar
2026-08-29 8:45 ` Alejandro Colomar
2026-08-29 8:52 ` Alejandro Colomar
2026-08-29 9:02 ` Alejandro Colomar
2026-08-29 9:39 ` Ingo Schwarze
2026-08-29 13:10 ` configure separate from make or not (was: Using LS/LE) Alejandro Colomar
2026-08-29 15:31 ` configure separate from make or not Ingo Schwarze
2026-08-29 20:49 ` Alejandro Colomar
2026-08-30 13:17 ` Alejandro Colomar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox