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
signature.asc
Description: PGP signature
