Executable makefiles

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


all:            shoutout.txt dup.txt

                rm -f shoutout.txt dup.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
[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
[standage@lappy make-demo]


  1. Cartman Brah

    On both arch and mint I’m getting a /usr/bin/env: make -f: No such file or directory

    That kind of shebang doesn’t seem to work.

    • Daniel Standage

      I may also have seen error messages like that on various OSs (I haven’t tracked which ones). In that case, I simply have to hard-code the path of the make command into the shebang.

      For robust distribution-worthy software it would be better to have some kind of automated “install” task that copies the makefile (or edits it in place) and puts the correct make path on the shebang. For small simple scripts, this is overkill and I simply edit the shebang manually.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s