I’ve talked before about the merits of using
Make and makefiles to implement bioinformatics pipelines. But I had a revelation today: just as one can use the shebang (
#!) to run Perl, Python, Ruby, Bash, or other scripts without calling the interpreter directly, I should be able to use the shebang to make a makefile executable. Simply place
#!/usr/bin/env make on the first line of the makefile, make sure you have execute permissions, and then you’re all set, right?
Well, there’s one gotcha. The problem with using just
#!/usr/bin/env make as the shebang is that the name of the script being executed is implicitly placed as the final argument on the shebang line.
Make therefore treats the makefile as a target rather than an actual makefile. With that in mind, the fix is simple: add the
-f flag to indicate the script is a makefile and not a target. A big thank you goes out to this StackOverflow thread for providing a clear solution to this problem.
The example below uses a trivial makefile to demonstrate how executable makefiles can be written and executed.
[standage@lappy make-demo] ls -lh run-it -rwxr-xr-x 1 standage staff 218B Nov 21 23:53 run-it [standage@lappy make-demo] cat ./run-it #!/usr/bin/env make -f MESSAGE=Dude all: shoutout.txt dup.txt clean: rm -f shoutout.txt dup.txt shoutout.txt: echo $(MESSAGE) > shoutout.txt dup.txt: shoutout.txt cp shoutout.txt dup.txt cat dup.txt [standage@lappy make-demo] ./run-it echo Dude > shoutout.txt cp shoutout.txt dup.txt cat dup.txt Dude [standage@lappy make-demo] ./run-it clean rm -f shoutout.txt dup.txt [standage@lappy make-demo] ./run-it MESSAGE=Sweet echo Sweet > shoutout.txt cp shoutout.txt dup.txt cat dup.txt Sweet [standage@lappy make-demo]