0

Let us suppose we use GNU Make on Linux for the purpose of this question.

As a regular shell script writer, the Makefile scripting seems a little odd to me.

Anyways, that is opinion-based, so straight to my question:

I found a way for me to write Makefiles a little bit more like shell scripts.

That being a line break / continuation character usage: \

Example beginning of my Makefile:

DESTDIR ?=
PREFIX ?= /usr/local/bin
install_path := $(DESTDIR)$(PREFIX)
encrypt_script := encrypt-file-aes256
decrypt_script := decrypt-file-aes256
distrib_name := openssl-encryption
this_file := $(lastword $(MAKEFILE_LIST))

.PHONY: check

check: $(encrypt_script) $(decrypt_script)
    @tput bold; tput setaf 3; echo Target: $@; echo; tput sgr0
    @if [ -f SHA512SUM ]; then \
        ( sha512sum --check SHA512SUM && \
            ( tput bold; tput setaf 2; echo; echo "Ok. You may use 'sudo make install' or '(sudo) make install PREFIX=SomeDir' command now."; tput sgr0 ) || \
            ( tput bold; tput setaf 1; echo; echo "ERROR: Files hash sum mismatch!"; echo; tput sgr0; exit 1 ) \
        ) \
    else \
        $(MAKE) --file=$(this_file) SHA512SUM; \
    fi

Have I totally crossed the line, or is it in common concept acceptable?

To avoid closing on opinion-based, please avoid your personal preferences, and quote sources.

Here is just a snippet of the code. You can find the whole Makefile without these changes here.

Vlastimil Burián
  • 3,024
  • 2
  • 31
  • 52
  • Why do you *want* Makefile to be more like a shell script? Write a shell script then if that's what you want. The purpose of `make` is to track dependency relationships between files. – tripleee Oct 14 '18 at 08:43
  • Also, pet peeve, don't sprinkle your `Makefile` with `@`. Use `make -s` if you find the output distracting; but squelching it completely makes debugging hard and cumbersome. – tripleee Oct 14 '18 at 08:44
  • Note that each command within a rule *is* essentially [treated as a shell script](https://www.gnu.org/software/make/manual/make.html#Execution). – G.M. Oct 14 '18 at 08:45
  • A better design altogether would be to have `install` fail if its prerequisites are not met. – tripleee Oct 14 '18 at 08:45
  • Maybe also find out about `printf`. – tripleee Oct 14 '18 at 08:46

1 Answers1

2

Breaking a complex recipe action across multiple lines is good and sound practice; but excessively long or complex invocations of shell script are a sign that you are doing it wrong. Maybe break out the logic to a separate script, or rethink your approach.

For example, I would simply refactor this to

install:
    sha512sum --check SHA512SUM
    : the rest of your exisiting install target here

This will fail if SHA512SUM is missing, or if the actual check fails.

If you want colored human-readable output or animated hamsters when this happens, write a wrapper script.

tripleee
  • 175,061
  • 34
  • 275
  • 318