[HN Gopher] GNU Make Standard Library
       ___________________________________________________________________
        
       GNU Make Standard Library
        
       Author : ingve
       Score  : 78 points
       Date   : 2025-02-05 07:30 UTC (15 hours ago)
        
 (HTM) web link (gmsl.jgc.org)
 (TXT) w3m dump (gmsl.jgc.org)
        
       | shakna wrote:
       | I wonder how thread-safe the memoisation and/or ALists are?
       | Make's version of parralel processing is a very fun little thing,
       | but has a few quirks around recursion limits that can bite you
       | when going off the beaten path.
       | 
       | [0]
       | https://www.gnu.org/software/make/manual/html_node/Options_0...
        
       | jgrahamc wrote:
       | I guess this is here because it's been 20 years and I blogged
       | about it on Monday: https://blog.jgc.org/2025/02/twenty-years-of-
       | gnu-make-standa...
        
       | t43562 wrote:
       | GNU make now has a load directive which lets you load up
       | functions written in C                   -load my_module.o
       | 
       | Your makefile can contain instructions to build my_module.o and
       | they will be automatically triggered.
       | 
       | For example you can create an equality test that works in an
       | expression (ifeq can't be used as part of an expression
       | obviously). For example                 FILENAME=file.$(if
       | $(equals $(compression_level),0),tar,.tar.bz3)
       | 
       | The C for this function (without includes and export directives):
       | char *       func_equals (const char *func_name, unsigned int
       | argc, char **argv)       {           char *result = NULL;
       | if (strcmp(argv[0], argv[1]) == 0) {               result =
       | gmk_alloc(strlen(argv[0]) + 1); /* not handling failure for
       | simplicity */               strcpy(result, argv[0]);           }
       | return result;       }
       | 
       | This can be done with a macro but it's ugly and verbose. Macros
       | also slow makefile parsing a lot and for a large build like e.g.
       | an operating system this makes a big difference - it's a penalty
       | you pay every time you run "make" even if you only changed 1
       | file.
       | 
       | There are plenty of things you cannot do with macros too.
       | $(shell) is a getout card but it drastically slows down large
       | makefiles.
       | 
       | Your module has a setup function which gets called when it's
       | loaded and this adds the function into gmake:                 int
       | equals_gmk_setup (const gmk_floc *flocp)       {
       | gmk_add_function ("equals", func_equals, 2, 2, GMK_FUNC_DEFAULT);
       | return 1;       }
       | 
       | Things that are hard/slow to do with macros like arithmetic -
       | comparing, adding and so on are even better candidates. A hash
       | function is great for generating intermediate target names that
       | aren't too long for the filesystem.
       | 
       | My favorite one that I've done is embedding a python interpreter
       | into make - this is very convenient as it's MUCH faster than
       | running a process from $(shell) and it keeps state between uses
       | which can be useful.
        
         | bandrami wrote:
         | GNU Make also embeds GNU Guile, a criminally underused feature:
         | 
         | https://www.gnu.org/software/make/manual/html_node/Guile-Int...
        
           | srik wrote:
           | TIL thank you!
        
             | bandrami wrote:
             | I sometimes wonder if we would even have autotools or cmake
             | if people just knew about this one simple trick
        
               | o11c wrote:
               | Autotools is designed to solve one very important
               | problem: how do you build the GNU tools in the first
               | place if all you have is some obscure Unix from the
               | 1980s. If you already have gnu make, gnu bash, gnu
               | binutils, gnu coreutils, etc. installed then autotools is
               | pointless.
               | 
               | I have yet to find evidence of cmake solving a problem
               | (or even having design), though I guess `ccmake` would be
               | kind of cool if it weren't full of nonsense?
        
               | t43562 wrote:
               | I see Autotools as sort of cool if you're porting to a
               | new platform - the tests find out what works and if
               | that's not enough then you have to make some effort to
               | get around it. If you're lucky, however, you put your
               | autotooled code on some completely new OS/hardware and it
               | just builds.
               | 
               | Nowadays the proportion of people who are porting the
               | code is probably much smaller but it's still a way of
               | keeping code working on unix with various compiler,
               | architecture variations.
               | 
               | IMO cmake just includes windows more effectively - for
               | autotools you'd probably be forced down the cygwin route.
               | I find it a bit easier to work with but it's still a
               | nightmare from hell sometimes.
        
               | bandrami wrote:
               | Though there's also gnulib, which as part of the
               | autotools process simply replaces system functions with
               | their own stubs. It was a great idea, briefly, and then
               | it became a fiasco.
        
               | wichert wrote:
               | Even with all the GNU tools available there are still a
               | lot of system-specific things that you may need to know:
               | supported C version, supported C++ version, how to invoke
               | the compiler, correct compiler flags for warnings /
               | desired C or C++ version / etc, where to install things,
               | how to install them and set the right owner and
               | permissions and many many more. Autotools (and cmake) can
               | figure all of that out for you. If you operate in a
               | monoculture and, for example, only deal with a single
               | Linux distribution on a single architecture most or all
               | of this may not be relevant for you. But if you target a
               | more diverse set of environments it can save you a lot of
               | headaches.
        
               | jcranmer wrote:
               | One of the other things that autotools does that cmake
               | does (admittedly badly) is provide a "configure" step
               | that gives a much more controllable interface into
               | enabling or disabling features of a program.
               | 
               | The problem with autoconf in particular is that it spends
               | a lot of time trying to paper over the compatibility
               | issues of ancient Unixes, whereas modern portability
               | tends to rely more on a concept of a portable abstract
               | system layer. The latter means that most of the work a
               | configure step needs to do isn't "does your system have
               | $UNIX_SYSTEM_CALL" but instead "what OS is this."
        
               | t43562 wrote:
               | Make's BIG problem (IMO of course) is that the commands
               | are executed in the system shell.
               | 
               | If make supplied it's own shell language, a simplified
               | one, then everything would be fantastic.
               | 
               | For one thing, cross platform builds would be much easier
               | to get working as there would be no issue about "is the
               | default shell bash or ash or sh or dash or ksh or
               | whatever" and on Windows there would be no need to use
               | cygwin.
               | 
               | The other thing is there would not need to be such a huge
               | clash between the way expansion works in shells versus
               | make which is very confusing when you combine the two.
        
               | rixed wrote:
               | Yes, but where do you stop? In make shell one would
               | routinely call rm, sed, find... should they be included
               | too? So instead of make including a shell, it would be
               | simpler if busybox included a make.
        
               | boris wrote:
               | > If make supplied it's own shell language, a simplified
               | one, then everything would be fantastic.
               | 
               | We did exactly that in build2, a modern make re-thought.
               | And we provide a bunch of standard utilities like sed,
               | find, etc., that work the same everywhere, including
               | Windows. Here is an example of a non-trivial recipe: http
               | s://github.com/build2/libbuild2-autoconf/blob/17f637c1ca.
               | ..
        
           | o11c wrote:
           | In practice, Guile is usually not compiled in. Whereas I've
           | _never_ seen a version of make without `load` and its
           | supporting infrastructure.
        
             | bandrami wrote:
             | Debian gives you the option, with make and make-guile
             | equivalent packages. IIRC Slackware simply compiles it in
             | (guile already being there) and Fedora/RHEL leave it out
             | entirely.
        
           | jhoechtl wrote:
           | Not for Windows
        
         | dima55 wrote:
         | That's great. Thanks for pointing it out.
        
           | t43562 wrote:
           | Delighted! :-) Glad someone found it a help
        
       | p4bl0 wrote:
       | Okay who will be doing this year's Advent of Code in GNU Make?
        
         | throwfgtpwd234 wrote:
         | What we really need is a C to GNU Make transpiler written in C
         | just so it can translate itself.
        
           | phtrivier wrote:
           | But what system would you to build that ?
        
             | throwfgtpwd234 wrote:
             | GNU Make and GCC, of course.
        
       | throwfgtpwd234 wrote:
       | OP FYI: US copyright law doesn't recognize or require a range of
       | years, only the date of first publication. Many organizations
       | have decided to omit (the) year(s) altogether.
       | https://blog.ntpsec.org/2020/02/15/copyright-year.html
        
         | jgrahamc wrote:
         | Good to know. I tend to use them as markers of "I started
         | working on this in year XXXX and I last worked on it in year
         | YYYY".
        
         | nemoniac wrote:
         | Check the first comment on the linked page for counterpoint.
         | 
         | Also note that copyright laws exist outside the US and may
         | differ.
        
       | rkangel wrote:
       | I have written some large build systems entirely in Make. More
       | complex things tend to rely on templates, but you can build
       | arbitrary things, with two main limitations:
       | 
       | The error messages are awful, particularly if using templates.
       | "Unexpected separator. Stop" is a classic, with no indication
       | where in your 2k lines of Make it might be.
       | 
       | You can't have file or folder names with spaces in (usually
       | including any parent folder to where your code is checked out). A
       | "list" in Make is a series of strings separated by spaces. There
       | are various workarounds that people suggest, but none of them
       | work consistently across platforms. You just have to avoid
       | spaces. At least this is less bad since Windows stopped using
       | "Documents and Settings" for "home" folders.
        
         | dima55 wrote:
         | GNU Make now has a debugger (`apt install remake`) that eases
         | your first pain point a lot
        
           | bonzini wrote:
           | Even then the problem with doing complicated stuff in Make is
           | that it's very hard to reproduce the environment that
           | triggered the bug in the first place.
           | 
           | I came to the conclusion that you need to treat all of the
           | build system as a linear process, which in Make would mean
           | for example not using "=" at all except to define functions,
           | only use ":=". With this kind of discipline I never really
           | needed a debugger, but really Make is not the right language
           | to write complex logic.
           | 
           | Personally I am a fan of (and contributor to) Meson. It's not
           | perfect but it strikes a good balance between what is in the
           | basic package and what you can do in your build script, and
           | by keeping the build phases separate it really helps with
           | keeping things understandable. The lack of functions can be
           | annoying (and in general I wish it could use Starlark as the
           | language), but it doesn't hurt if you follow the same
           | principle and treat the build script as a data flow process,
           | with each phase producing data structures for the next one.
           | So I think it's generally a good principle to follow.
        
       | beardyw wrote:
       | Make is just the epitome of software development:
       | 
       | Started as a simple idea
       | 
       | Required more sophistication
       | 
       | Became something no one person really understands
        
         | dima55 wrote:
         | Did you try reading the manual?
        
           | RegW wrote:
           | Certainly not! That would be a faux pas.
        
           | high_na_euv wrote:
           | When software requires you to read manual, then it is strong
           | hint that it has poor UI UX
           | 
           | Like, you dont read web browser manual to use it, even when
           | using advanced features like debugger or dev console
           | (advanced in compare to non-computer person)
        
             | armitron wrote:
             | Make is a power tool and power tools require effort to
             | fully understand and master (though the base case in Make
             | is surprisingly simple). It also has great documentation
             | (which is something newer generations either don't
             | appreciate or don't care about).
        
           | rixed wrote:
           | Can't find it on youtube, link?
        
             | gpderetta wrote:
             | sarcasm?
        
               | rixed wrote:
               | Indeed. Should delete but it's too late.
        
       | davemp wrote:
       | I've written a fair amount of Makefiles and bounced off of cmake.
       | Recently I've started using zig to build some C++ projects and
       | will not be switching back.
       | 
       | Having your build tool just be a library in a good general
       | purpose language is the right move. Why use unergonomic hacks
       | like the OP when you can use a sane language? My build.zig files
       | have LSP completions and similar syntax (or the same) as what I'm
       | building.
       | 
       | I put make solidly in the pile of tools that are only still
       | around because of network effects. We'd have switched to
       | something better if it weren't defacto installed by every distro
       | and had to make justifications to sys admins to install
       | alternatives.
        
         | aeonik wrote:
         | Same reason I like Clojure tools.build. Any other way feels a
         | little ridiculous to do it any other way.
        
       | EPWN3D wrote:
       | Just ran across this last week and pulled it into my Makefiles.
       | Really nice.
        
       | anthk wrote:
       | git clone git://bitreich.org/english_knight
       | 
       | You don't need more.
       | 
       | I wish everyone used mk instead of bloated software.
       | 
       | Unix grew up too much.
        
         | ta8645 wrote:
         | That is one seriously funky website; I will not recover from
         | the experience soon.
         | 
         | For anyone who doesn't want to clone the above repo,
         | english_knight turns out to just be a template for idiomatic
         | makefiles. I pasted the relevant file from the repo here:
         | 
         | https://nopaste.net/english_knight
        
           | anthk wrote:
           | Well, you should access bitreich over gopher :)
           | 
           | gopher://bitreich.org
           | 
           | Much better.
        
             | ta8645 wrote:
             | You're right. That was less traumatic, but still fun, heh.
        
       ___________________________________________________________________
       (page generated 2025-02-05 23:01 UTC)