Saturday, September 01, 2018

Re: make(1) and multiple outputs

Hi Kristaps,

Kristaps Dzonsons BSD.LV wrote on Fri, Aug 31, 2018 at 09:23:33AM +0200:

> Short: is there a way to manage multiple outputs from a single command
> with OpenBSD's make(1)?
>
> Longer story. I have a site that generates a few hundred articles using
> sblg(1). Each output article is indexNNN.html, which depends upon every
> input indexNNN.xml. So a change to any indexNNN.xml must result in
> rebuilding all indexNNN.html using a single command.
>
> In GNU make, I can use the pattern substring match to effect this:
>
> all: index001.html index002.html
>
> index001%html index002%html: index001.xml index002.xml
> sblg -L index001.xml index002.xml

What is wrong with simply

index001.html index002.html: index001.xml index002.xml
sblg -L index001.xml index002.xml

as documented in make(1),

https://man.openbsd.org/make.1#DEPENDENCY_LINES

It works for me, see the mock-up example below.

I have no idea what '%' means, though, and neither the gmake(1)
manual page nor the gmake info page appear to mention it.

> But obviously that's GNU-only. It is, as a fallback, possible to have
> sblg(1) create one output per input and play nice with make(1):
>
> index001.html: index001.xml index002.xml
> sblg -C index001.xml index001.xml index002.xml
>
> But with hundreds of articles (each of which depends upon parsing
> hundreds of articles), those are a lot of wasted cycles.
>
> I currently just use the GNU make, but I'd rather use only stock
> components on the server. Any thoughts?

Here is my test:

$ cat Makefile
all: output1 output2

output1 output2: input1 input2
sh ./sblg

$ cat sblg
echo running sblg... 1>&2
cat input1 input2 > output1
cat input2 input1 > output2
echo sblg done. 1>&2

$ cat input1
content 1

$ cat input2
content 2

$ make
sh ./sblg
running sblg...
sblg done.

$ cat output1
content 1
content 2

$ cat output2
content 2
content 1

$ sed -i 's/2/3/' input2

$ make
sh ./sblg
running sblg...
sblg done.

$ cat output1
content 1
content 3

$ cat output2
content 3
content 1

make(1) does the right thing and only runs ./sblg once, even though
output from "make -n" is misleading:

$ rm -f output*
$ make -n
sh ./sblg
sh ./sblg

No comments:

Post a Comment