Sean Allred
Sean Allred

Reputation: 3658

How can I simplify this Makefile to make it less repetitive?

Make is one of those technologies where I go back and forth between whether or not I understand it.

This is certainly one instance where I know I must be doing something wrong, since Make was developed to make these tasks less repetitive.

all: 24.1 24.2 24.3

24.1:
    evm install emacs-24.1-bin || true
    emacs --version
    emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit
24.2:
    evm install emacs-24.2-bin || true
    emacs --version
    emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit
24.3:
    evm install emacs-24.3-bin || true
    emacs --version
    emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit

How can I edit this Makefile to only lay out the test sequence once but be able to test against multiple versions?

Upvotes: 2

Views: 298

Answers (3)

Edouard Thiel
Edouard Thiel

Reputation: 6238

Try this:

VERSIONS = 24.1 24.2 24.3

all :: $(VERSIONS)

$(VERSIONS) ::
    evm install emacs-$@-bin || true
    emacs --version
    emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit

The :: is a special kind of rule, that puts the target as phony (and has other properties, too).

Upvotes: 5

Vucar Timnärakrul
Vucar Timnärakrul

Reputation: 552

I have to admit that turning to ‘last resort’ strategies always makes me queasy: it feels as if going against the grain of the tool. BSD make on the other hand allows explicit looping constructs, hence getting rid of the repetitive rules is straightforward:

VERSIONS = 24.1 24.2 24.3
all: ${VERSIONS}

.for VERSION in ${VERSIONS}
${VERSION}:
    evm install emacs-${VERSION}-bin || true
    emacs --version
    emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit
.endfor

I’m well aware that this solution almost surely won’t help you at all; switching make implementation is almost certainly out of the question. BSD make is sorely underrepresented though, so I thought it might be useful for other people to have an alternative approach documented.

As MadScientist correctly pointed out, GNU make doesn’t support any of the ‘dot constructs’ like .for, which are special to BSD make. However, this question suggests a few other looping techniques that might be applicable to GNU make: How to write loop in a Makefile?

Upvotes: 2

MadScientist
MadScientist

Reputation: 101081

How about:

all: 24.1 24.2 24.3

%:
        evm install emacs-$@-bin || true
        emacs --version
        emacs --batch -L . -l ert -l test/tests.el -f ert-run-tests-batch-and-exit

Upvotes: 2

Related Questions