Live data from Hacker News

Polyglot Makefiles

agdr.org

21–30 of 44 posts

Re: Polyglot Makefiles

#21

For complicated pipelines that I want to reuse multiple times, I have turned Makefiles into executables by putting this at the top: #!/usr/bin/make -f And then putting them in my $PATH. I run them with arguments like: $ process-data.mk INTSV=a.tsv DB=largefile.gz OUTDIR=finished This makes me feel like I've sold my soul to the devil, and that I'm just living on borrowed time until it all fails and falls apart. It has…

-f is guaranteed by POSIX, and #! is de facto portable.[1] My criteria for shame is, "will this silently break in the future?". I think you're good. It's not my style, but if it were something I came across at work, so long as it worked well it wouldn't even cross my mind to try to "fix" it.

FWIW, using make -f in the shebang is also done for debian/rules in Debian package builds. I don't know if it serves any real purpose. I suppose it permits one to write a bespoke script for building targets without using make.[2] I guess I wouldn't be surprised if someone, somewhere depended on that capability, given how old and widespread Debian packages are.

[1] /usr/bin/env make -f would be better, but then you run afoul of the problem that you can't portably pass more than a single explicit shebang command argument.

[2] Which I see now is a bonus to your process-data.mk script. It could be replaced with a non-make version without effecting callers.

Re: Polyglot Makefiles

#22
post #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 o…

How does it deal with wildcard rules? I would bet it gets complicated when you start having chained wildcard rules that have also side effects.

Re: Polyglot Makefiles

#23
post #9

Earlier quoted context omitted.

The shell is specific to each target. So doing `make ruby bash python docker` works. It even works in parallel if you do `make -j`. Edit: I'm the author.

And what happens if there's overlap between the targets?

Define 'overlap'?

Re: Polyglot Makefiles

#24
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

"make help" is definitely not a standard. For all I know "make help" builds help.exe. But there is a standard way to get available commands: Just look at the README or open the Makefile with a text-editor!

The lack of a standard argument for getting help doesn't make it problematic for use as a command runner. You can't get atomatically all available commands from a Makefile just like you can't get all command-line flags from an executable. The program/Makefile has to provide it by itself.

Re: Polyglot Makefiles

#25
post #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 o…

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

I would think because it's useless. The targets in a Makefile are very often just internal and aren't always meant to be run by the user.

Re: Polyglot Makefiles

#26
post #19

Earlier quoted context omitted.

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 o…

> remake --targets; No idea why this hasn't been merged upstream I would think because it's useless. The targets in a Makefile are very often just internal and aren't always meant to be run by the user.

It has an interactive debugger, which is not useless. Clearly.

Re: Polyglot Makefiles

#27
post #19

Earlier quoted context omitted.

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 o…

How does it deal with wildcard rules? I would bet it gets complicated when you start having chained wildcard rules that have also side effects.

There's --targets and --tasks to handle such things, but it really depends on the Makefile in question. If you really want to know how it behaves, apt install remake.

Re: Polyglot Makefiles

#28
post #26

Earlier quoted context omitted.

> remake --targets; No idea why this hasn't been merged upstream I would think because it's useless. The targets in a Makefile are very often just internal and aren't always meant to be run by the user.

It has an interactive debugger, which is not useless. Clearly.

I was just referring to the --targets option which I thought was meant as an answer to the missing standard help.

Re: Polyglot Makefiles

#29
I wish someone would write a modern alternative to GNU Make. I've looked and there don't seem to be any. The closest is Ninja but it doesn't seem to be intended to be hand written.

Re: Polyglot Makefiles

#30

For complicated pipelines that I want to reuse multiple times, I have turned Makefiles into executables by putting this at the top: #!/usr/bin/make -f And then putting them in my $PATH. I run them with arguments like: $ process-data.mk INTSV=a.tsv DB=largefile.gz OUTDIR=finished This makes me feel like I've sold my soul to the devil, and that I'm just living on borrowed time until it all fails and falls apart. It has…

I can see two areas in which it might break.

I might put #!/usr/bin/env make -f in case it's somewhere in else in PATH.

Also some systems (BSD, old commercial Unix) have non-gnu-compatible make and sometimes call their gnu make port "gmake" or "gnumake".

Post reply on HN