Friday, April 8, 2011

How can I use bash syntax in Makefile targets?

I often find bash syntax very helpful, e.g. process substitution like in diff <(sort file1) <(sort file2).

Is it possible to use such bash commands in a Makefile? I'm thinking of something like this:

file-differences:
    diff <(sort file1) <(sort file2) > $@

In my GNU Make 3.80 this will give an error since it uses the shell instead of bash to execute the commands.

From stackoverflow
  • You can call bash directly, use the -c flag:

    bash -c "diff <(sort file1) <(sort file2) > $@"
    

    Of course, you may not be able to redirect to the variable $@, but when I tried to do this, I got -bash: $@: ambiguous redirect as an error message, so you may want to look into that before you get too into this (though I'm using bash 3.2.something, so maybe yours works differently).

  • From the GNU Make documentation,

    5.3.1 Choosing the Shell
    ------------------------
    
    The program used as the shell is taken from the variable `SHELL'.  If
    this variable is not set in your makefile, the program `/bin/sh' is
    used as the shell.
    

    So put SHELL := /bin/bash at the top of your makefile, and you should be good to go.

  • You can call bash directly within your Makefile instead of using the default shell:

    bash -c "ls -al"
    

    instead of:

    ls -al
    

    Or force make to use a specific shell with either (only export once):

    export SHELL=$(whence bash)
    make ...
    

    or:

    SHELL=$(whence bash) make ...
    
  • If portability is important you may not want to depend on a specific shell in your Makefile. Not all environments have bash available.

0 comments:

Post a Comment