1. 34
  1. 20

    GNU M4 seems extremely unmaintained. It’s fixed in GNU M4 1.4.19 which came out in may this year, but ever since a glibc update which came out in 2018, M4 has been impossible to build with the latest glibc. So GNU M4 was impossible to build with GNU’s libc for 3 years.

    I don’t know if I would trust a system which just accepts to be unbuildable for many years due to a change in a dependency from the same organization. I don’t know what’s going on at GNU but it’s not good.

    This is a patch Arch Linux carried from late 2018 to mid 2021 as a workaround: https://github.com/archlinux/svntogit-packages/blob/052a1c13487831226608223ce8b5406ba4a33e19/trunk/m4-1.4.18-glibc-change-work-around.patch

    1. 11

      GNU is an organisation to the extent they’ve been assigned a lot of copyrights, but, maintainership doesn’t appear very organised.

      1. 3

        On the other hand it’s impressive that the massive ecosystem of software that depends on m4 was largely unaffected by upstream completely dropping the ball. Don’t think many languages have that going for them.

        1. 9

          Here’s the patch that Debian applies to fix this issue: https://sources.debian.org/src/m4/1.4.18-5/debian/patches/01-fix-ftbfs-with-glibc-2.28.patch/

          Here’s the patch that Fedora applies to fix this issue: https://src.fedoraproject.org/rpms/m4/blob/814d592134fad36df757f9a61422d164ea2c6c9b/f/m4-1.4.18-glibc-change-work-around.patch

          Here’s the patch that Void Linux applies to fix this issue: https://github.com/void-linux/void-packages/blob/master/srcpkgs/m4/patches/fix-glibc-2.27.patch

          Here’s the patch that NixOS applies to fix this issue: https://github.com/NixOS/nixpkgs/blob/nixos-21.05/pkgs/development/tools/misc/gnum4/default.nix

          Alpine linux uses musl so it doesn’t need a patch. BSD’s I don’t know enough about to know what libc they use, but they will also patch broken upstream software as part of their package systems.

          It’s pretty easy to be completely unaffected by upstream completely dropping the ball when midstream is full of people picking it back up for them.

          1. 4

            The BSDs have their own implementations of libc and m4, so they were unaffected by this issue for the most part

            1. 1

              Exactly! Very robust ecosystem.

        2. 19

          We have plenty of good templating languages: Jinja2, Liquid, Askama, Phoenix.Template, etc. They generally don’t need arcane quoting rules, are happy to ingest arbitrary data from outside programming languages, don’t have insane scoping for declarations, etc. I personally am happy to leave m4 in the mausoleum where it belongs.

          1. 23

            No! We Must Use The Tools Of Our Ancestors, Else We Have Strayed From The True Path! Yea, Even Unto The Lowliest Preprocessor.

            1. 4

              “M4 is the standard text editor preprocessor.”

              M4, the greatest preprocessor of all.


              1. 2

                M4 is a true Tool of The Minimalist Path.

                1. 8

                  M4 will not corrupt your precious bodily fluids!

                  1. 4

                    I don’t mind the templates…. but I do deny them my essence.

                  2. 4

                    TIL it was designed by K&R. Always thought it was a GNU thing because I associated it with autotools.

                2. 6

                  We have plenty of good templating languages

                  There are situations when you don’t want to commit to a programming language runtime but you still need a templating language. That’s been the usecase I’ve found for m4. (Not that I disagree with any of the criticism of it being arcane and hard to debug, I just haven’t found a language-agnostic replacement for it yet. Pandoc is large and for these situations is a bit too large (container configs come to mind.))

                  1. 2

                    The snarky argument is that m4 is also bound to a programming language runtime, it just happens to be C. :-P That’s not actually correct though.

                    This is actually an interesting distinction, and also possibly one of the things that makes m4 such a bear to do complicated things with while making it nice to do simple things with. All the other tools I named are designed to be controlled from a programming language, not a standalone exe. That means that they have more or less that programming language’s data model, not just plain text or their own slightly-half-assed data model, and also that you can pull some of the more complicated operations out of them or inject new functions into them, so that’s the source of a lot of their power, and you don’t need to do as much of your logic in macros.

                    On the flip side, there’s no real reason you couldn’t write a standalone Python/whatever program to run Jinja2 on arbitrary files and take its data from whatever source you want; command line args, inline declarations, JSON/TOML/whatever file input, etc. But that doesn’t seem to have become popular for some reason.

                    1. 2

                      On the flip side, there’s no real reason you couldn’t write a standalone Python/whatever program to run Jinja2 on arbitrary files and take its data from whatever source you want; command line args, inline declarations, JSON/TOML/whatever file input, etc. But that doesn’t seem to have become popular for some reason.

                      There’s a python program/library that does exactly that with jinja2: https://staticjinja.readthedocs.io

                      1. 2

                        The snarky argument is that m4 is also bound to a programming language runtime, it just happens to be C. :-P That’s not actually correct though.

                        Unfortunately I’ve already accepted the C runtime as dependency for most of my code 😛

                        I’ll be clear that given a choice I will pick a programming language’s templating environment over M4 any day. The only use for M4 is when you don’t want to do that. For me that’s usually for config files used around boot. I would really like to see something like M4 with its footprint that is less wonky than M4.

                        1. 1

                          There are a few compiled Jinja (or jinja-like) implementations in the wild. For example https://tera.netlify.app/docs is just 3 or so lines of code from a (basic) standalone, static tool which doesn’t require a runtime.

                          I’m sure there are people using it that way.

                    2. 13

                      I’ve used m4. I mean I’ve actually written it, not just copy-pasted stuff.

                      I liked it, but I’m a very strange person.

                      I appreciated the consistency and simplicity of its design. At the same time, I see why its extremely dense and unusual syntax creates a very high barrier to entry. Also, it’s inextricably linked to autoconf for most people who’ve worked with it, and I can see why having to learn an entire Turing-complete language to customize config scripts is not something everyone is thrilled by.

                      1. 4

                        No sendmail.mc/.cf configuration ever?

                        1. 7

                          Nooo, I had managed to finally forget Sendmail configuration and then I had to read this!

                        2. 2

                          FWIW I also really enjoy using m4, and I managed to get it deployed into production too LOL

                        3. 8

                          I think only me and the author think about m4 this way. I was using it some years ago to create templates for terraform and lately for deploying redash on Kubernetes.

                          I still think Exploiting the m4 macro language[pdf] is one of the best reading material on it.

                          Let’s give m4 a second life. Everyone is inventing a template language and we have one in front of us for 50 years or so.

                          1. 4

                            I know m4 is used in telecommunications somewhat - it’s on an OpenSIPS example page somewhere.

                          2. 11

                            Gross, right? m4 is great for macros and includes. Not super fun for general programming. But, like immigrants, it gets the job done.

                            Uh… what?

                            1. 22

                              I think it’s a reference to a lyric from Hamilton?

                              [LAFAYETTE] Immigrants:

                              [HAMILTON/LAFAYETTE] We get the job done


                              1. 2

                                Huh. Cool!

                              2. 9

                                I don’t know what’s more offensive: making light of the exploitation of immigrant labor, or referencing Hamilton.

                                1. 3
                                  1. 1

                                    Immigrants work hard?

                                    1. 1

                                      I think he is referencing the fact that immigrants are in many places known to be very hard workers and will “get the job done”.

                                    2. 5

                                      My first website used cpp(1) for templating.

                                      My second website used m4, as I couldn’t be bothered to match ' and " on each line. ;)

                                      1. 4

                                        OP here 👋

                                        m4 is a wacky, weird, fun language that I’ve had fun playing around with.

                                        Really enjoy the comments and content being shared here!

                                        1. 4

                                          I used to use m4 for generating my static site. Then when I went to write a blog post about m4, featuring m4 code snippets, it (understandably) started replacing the macros. It was hell to find a work around. I remember most of what I tried worked almost well enough with some odd exception. I ended up giving up on it eventually.

                                          1. 4

                                            I’m not 100% when and where I first encountered m4. It very well may have been in the colophon of technomancy.us where the author boasts that the entire site is “published via GNU M4, rsync, and a 12-line Makefile,” which was super attractive to the minimalist in me.

                                            There’s a big hat-tip to @technomancy

                                            1. 6

                                              Haha, wow. I think maybe I should have been a little more up-front that m4 is super bad at things like generating an atom feed on account of lacking an iteration facility. I mean just look at this shit: https://p.hagelb.org/feed.m4.html

                                              But other than that it’s worked really well for me. Even with the looping nastiness it beats debugging rubygems problems I’ve seen in other static HTML generation setups.

                                              1. 1

                                                Even with the looping nastiness it beats debugging rubygems

                                                Yeah, I used this for a company blog for a very long while. That ended with me freezing an ubuntu VM in time to be able to continue running it until we migrated away. Because every update to anything that even rhymed with ruby broke it.

                                                More recently, Hugo has been both very stable and good enough that I wouldn’t want to write m4 for this purpose, though :)

                                                1. 1

                                                  damn. do you have a snippet where m4 is perhaps better suited?

                                                  1. 3

                                                    Oh sure; like … basically every other page on the site I guess! http://p.hagelb.org/colophon.m4.html or http://p.hagelb.org/projects.m4.html

                                                    It’s really just looping that’s ugly. If M4 added an iteration macro it’d be perfect. Feels like a really stupid hill to die on, especially for a language that allows recursion.

                                              2. 3

                                                I have painful memories of debugging m4 use/misuse in sendmail and autotools. -shudder-

                                                1. 3

                                                  If you’re using Pandoc, as the OP was at first, you can do some amount of templating without any external tools. If you invoke Pandoc like

                                                  pandoc --to html --standalone < input.md

                                                  it will give you a full HTML document, with a DOCTYPE declaration and a <head> and everything. You can see the template Pandoc uses for this by running

                                                  pandoc --print-default-template html

                                                  If you tweak that template (e.g. by adding your own header and footer elements), you can then use

                                                  pandoc --to html --template my_template.html < input.md

                                                  to convert from a Markdown file (containing just the post body and maybe some metadata) to a complete HTML file. You can read about Pandoc’s template syntax here. It’s another syntax you’d have to learn, but… judging from the article, it would be a lot faster to get familiar with Pandoc’s template syntax than M4. (I’ve never tried building something as complex as an RSS feed with this, but I bet it’s possible.)

                                                  1. 2

                                                    I am reminded of the descriptions of “atmospheric programming” when the author talks about global state. I’m also reminded of why PHP is hard to maintain in the face of include().

                                                    1. 2

                                                      “atmospheric programming”

                                                      I read this thread and I felt my brain cells deteriorate. I really wish this was open source if only so I could stare into the abyss.

                                                    2. 2

                                                      I remember that Dan Luu(? Or some other famous blogger, maybe Yegge?) said in some article the most productive person he has watched code uses m4 as the main part of their editing workflow

                                                      1. 2

                                                        20 years ago when 64 MB was a nice amount of RAM for a sysadmin’s desktop, using Fvwm as a window manager meant I could use the FvwmM4 module, and have desktop menus which could open terminals providing hostnames and which would open windows which ssh’d to those hosts, etc etc. DRY across my SSH and window manager settings.

                                                        1. 1

                                                          Ah, I have memories of exploring M4 to create HTML. In 2002 I even wrote an article for Linux Magazine on the topic! The magazine is gone now, but I host a pdf copy of my article on my website.

                                                          I don’t use M4 any more. I now use Org mode, which has its own way of including things; thus I’ve ended up with Emacs running in a docker image on CircleCI to publish my blog. It’s quite complicated, and I hardly blog any more, and I wouldn’t be completely surprised if the two are linked.