diwakar_wagle
diwakar_wagle

Reputation: 13

bash builtin commands in makefile

Following rule to clean all the binary files in the makefile doesn't work.

SHELL:=bash
PHONY: clean
clean:
    for file in {"greedy","mario","pset1_mario","credit","hello"}; do \
        [[ -e "${file}" ]] && rm ${file}; \
    done

It gives following error message.

recipe for target 'clean' failed make: *** [clean] Error 1

It works if I invoke another shell script with the same command from the make file.

clean:
    bash ./cleanup.sh

Is there a way I can put these commands inside the makefile itself?

Upvotes: 1

Views: 603

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80921

Because the Error 1 isn't what you think it is.

Use SHELL:=/bin/bash -x in the makefile and you'll see that you aren't running what you expect to be running.

Specifically you forgot to escape the $ in the recipe from make so instead of testing each name in that list in the -e test you are testing the empty string ([ -e "" ]). This then fails each time through the loop.

The last time through the loop when that fails the for loop ends and since the last command in the loop exited with a failure return the entire loop ends with a failure return so make sees the script ending with a failure and reports that.

You want this:

SHELL:=bash
.PHONY: clean
clean:
        for file in {"greedy","mario","pset1_mario","credit","hello"}; do \
            [[ ! -e "$${file}" ]] || rm $${file}; \
        done

Note the double $$ on the shell variables and note the inversion of the test and conditional. make recipe lines need to return success unless you want them to terminate the make.

Also note .PHONY there. PHONY is just a normal target.

Update:

It is probably also worth pointing out that this snippet specifically gains nothing from the brace expansion or bash-specific [[ test and could just as easily be rewritten in a sh-compatible manner:

clean:
        for file in greedy mario pset1_mario credit hello; do \
            [ ! -e "$${file}" ] || rm $${file}; \
        done

Upvotes: 1

Related Questions