equivalent of pipefail in GNU make?

后端 未结 3 1543
失恋的感觉
失恋的感觉 2021-02-12 12:04

Say I have the following files:

buggy_program:

#!/bin/sh
echo \"wops, some bug made me exit with failure\"
exit 1

Makefile:

<         


        
3条回答
  •  再見小時候
    2021-02-12 12:58

    Here's a possible solution that doesn't require bash. Imagine you have two programs thisworks and thisfails that fail or work fine, respectively. Then the following will only leave you with work.gz, deleting fail.gz, ie. create the gzipped make target if and only if the program executed correctly:

    all: fail.gz work.gz
    
    work.gz:
        ( thisworks && touch $@.ok ) | gzip -c -9 >$@
        rm $@.ok || rm $@
    
    fail.gz:
        ( thisfails && touch $@.ok ) | gzip -c -9 >$@
        rm $@.ok || rm $@
    

    Explanation:

    In the first line of the work.gz rule, thisworks will exit with success, and a file work.gz.ok will be created, and all stdout goes through gzip into work.gz. Then in the second line, because work.gz.ok exists, the first rm command also exits with success – and since || is short-circuiting, the second rm does not get run and so work.gz is not deleted.

    OTOH, in the first line of the fail.gz rule, thisfails will exit with failure, and fail.gz.ok will not be created. All stdout still goes through gzip into fail.gz. Then in the second line, because fail.gz.ok does not exist, the first rm command exits with failure, so || tries the second rm command which deletes the fail.gz file.


    To easily check that this works as it should, simply replace thisworks and thisfails with the commands true and false, respectively, put it in a Makefile and type make.

    (Thanks to the kind people in #autotools for helping me with this.)

提交回复
热议问题