Live data from Hacker News

Polyglot Makefiles

agdr.org

11–20 of 44 posts

Re: Polyglot Makefiles

#11
post #8

Note that this article (like many, many others) assumes GNU Make. POSIX Make has neither .ONESHELL nor local macros. Neither do most built-in Make implementations in other OSes, like OpenBSD's bmake.

POSIX shell is also notoriously obtuse and difficult to use. As a big advocate of POSIX as a target, I don't blame anyone for using GNU make - or perhaps BSD make is a better lowest common denominator.

Personally, I try to use POSIX Makefiles, but I often find that they're most useful as a target for Makefile generators (in my case, these are usually a shell script called configure).

Re: Polyglot Makefiles

#12

Make was designed for building dependencies. I think it is always problematic to use it as a command runner (for example there is no standard way to list out the available commands). [just]( https://github.com/casey/just ) is a tool that feels similar to make but is designed explicitly for the purpose of running commands. I think of this as a simple CLI for your project workflow. You still really want to avoid puttin…

When you say, "there is no standard way to list out the available commands", do you mean like a `make help`?

https://gist.github.com/prwhite/8168133#gistcomment-3114855

Re: Polyglot Makefiles

#13
post #8

Note that this article (like many, many others) assumes GNU Make. POSIX Make has neither .ONESHELL nor local macros. Neither do most built-in Make implementations in other OSes, like OpenBSD's bmake.

POSIX shell is also notoriously obtuse and difficult to use. As a big advocate of POSIX as a target, I don't blame anyone for using GNU make - or perhaps BSD make is a better lowest common denominator. Personally, I try to use POSIX Makefiles, but I often find that they're most useful as a target for Makefile generators (in my case, these are usually a shell script called configure).

One person's obtuseness is other person's simplicity :-) . In all of my personal and some of my work projects I used nothing but portable features in Shell, Make, Sed, etc. Checking with multiple implementations where possible. As long as you use the right tool for the right job, there shouldn't be any problems.

The most common mistake of that sort that I've seen is people trying to do complex conditionals inside their makefiles when they clearly would be better off in a Shell script. (I'm looking at you, fans of ifeq.)

Re: Polyglot Makefiles

#14
post #12

Make was designed for building dependencies. I think it is always problematic to use it as a command runner (for example there is no standard way to list out the available commands). [just]( https://github.com/casey/just ) is a tool that feels similar to make but is designed explicitly for the purpose of running commands. I think of this as a simple CLI for your project workflow. You still really want to avoid puttin…

When you say, "there is no standard way to list out the available commands", do you mean like a `make help`? https://gist.github.com/prwhite/8168133#gistcomment-3114855

While you you could argue that this is a convention -- I'd say this isn't even a common one -- it's still a long way from being "standard".

Re: Polyglot Makefiles

#15

Make was designed for building dependencies. I think it is always problematic to use it as a command runner (for example there is no standard way to list out the available commands). [just]( https://github.com/casey/just ) is a tool that feels similar to make but is designed explicitly for the purpose of running commands. I think of this as a simple CLI for your project workflow. You still really want to avoid puttin…

Yes I agree with this. I use shell instead of make, because make wrapps shell and its syntax collides very poorly with it. For example, the PID is now $$$$ and not $$.

Most people forget to mark their targets .PHONY, so they have a subtle bug in their build (touch build; touch test).

----

But shell also suffers from the problem where it doesn't list the commands. I filed a bug for Oil shell here:

https://github.com/oilshell/oil/issues/751

I mentioned a couple other "frameworks" there like just, go, Taskfile, etc.

But it should really just be built into the shell, since it's so common. And there should be command completion too, which I think bash-completion has for Makefiles on many distros.

Apparently there is no standard name for this kind of "task runner". But I think shell makes a lot more sense than a custom format, because there are many instances where you need a simple loop or conditional. It scales better. (And Oil also fixes bad shell syntax while remaining compatible: http://www.oilshell.org/blog/2020/01/simplest-explanation.ht...)

If anyone wants to help let me know :) The code is plain Python and pretty hackable. However it generates fast C++, so you get the best of both worlds (in progress)

Re: Polyglot Makefiles

#16
post #8

Note that this article (like many, many others) assumes GNU Make. POSIX Make has neither .ONESHELL nor local macros. Neither do most built-in Make implementations in other OSes, like OpenBSD's bmake.

bmake is the implementation of make in NetBSD and FreeBSD. OpenBSD dropped bmake a long time ago and wrote their own implementation. OpenBSD make doesn't support ONESHELL, either, though.

Re: Polyglot Makefiles

#18
post #13

Earlier quoted context omitted.

POSIX shell is also notoriously obtuse and difficult to use. As a big advocate of POSIX as a target, I don't blame anyone for using GNU make - or perhaps BSD make is a better lowest common denominator. Personally, I try to use POSIX Makefiles, but I often find that they're most useful as a target for Makefile generators (in my case, these are usually a shell script called configure).

One person's obtuseness is other person's simplicity :-) . In all of my personal and some of my work projects I used nothing but portable features in Shell, Make, Sed, etc. Checking with multiple implementations where possible. As long as you use the right tool for the right job, there shouldn't be any problems. The most common mistake of that sort that I've seen is people trying to do complex conditionals inside the…

You can implement conditionals semi-portably. See https://github.com/wahern/autoguess/blob/master/Makefile.gue..., which works with GNU Make, NetBSD/FreeBSD make, OpenBSD make, and Solaris make. Alas, it doesn't work with AIX's native make.

Once POSIX standardizes "!=" then POSIX-portable conditionals will be possible using the same technique as above, replacing, e.g. OS = $(shell $(OS.exec))$(OS.exec:sh) with just OS != $(OS.exec). Though, you'd need to wait for Solaris, AIX, and macOS gmake[1] to add support for !=.

Alternatively, if you add an extra level of indirection using .DEFAULT to capture and forward make invocations, you can simply pass OS, etc, as invocation arguments. Indirection solves everything, though, so that's cheating.

[1] Apple's ancient GNU Make 3.81 predates != support. :(

Re: Polyglot Makefiles

#19

Make was designed for building dependencies. I think it is always problematic to use it as a command runner (for example there is no standard way to list out the available commands). [just]( https://github.com/casey/just ) is a tool that feels similar to make but is designed explicitly for the purpose of running commands. I think of this as a simple CLI for your project workflow. You still really want to avoid puttin…

The tool you want is remake: http://bashdb.sourceforge.net/remake/

This is GNU Make + a few patches. So it's 100% compatible. And you get an interactive debugger, and lots more stuff. For instance, to list out the commands:

  remake --targets
No idea why this hasn't been merged upstream.

Your larger point really stands, though: if you're just running commands, you shouldn't be using Make. But it is abused in that way often, so...

Re: Polyglot Makefiles

#20

Make was designed for building dependencies. I think it is always problematic to use it as a command runner (for example there is no standard way to list out the available commands). [just]( https://github.com/casey/just ) is a tool that feels similar to make but is designed explicitly for the purpose of running commands. I think of this as a simple CLI for your project workflow. You still really want to avoid puttin…

I didn't generate any files in the examples for simplicity. But you could imagine a workflow where Python generates some data and then you use R to plot it + run some statistical tool.
Post reply on HN