bashubuntumakefilegnu-makebrace-expansion

How to handle shell expansions in GNU Make under Ubuntu?


Given this very simple Makefile:

all:
    @mkdir -pv test/{a,b}

I get this output on OS X 10.6.8 and CentOS 5.5:

mkdir: created directory `test'
mkdir: created directory `test/a'
mkdir: created directory `test/b'

But on Ubuntu 11.04 I get this:

mkdir: created directory `test'
mkdir: created directory `test/{a,b}'

Running the command mkdir -pv test/{a,b} manually in the shell on all platforms gives the expected result.

The version of GNU Make is the same on all platforms:

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program is built for [PLATFORM]

What's different under Ubuntu and why doesn't the shell expansion work there?


Solution

  • The problem is probably that Make spawns /bin/sh. It is usually a symlink to your system's default shell.

    Option 1

    You could make sure it points to bash (as this is a bashism). Probably, it is now /bin/dash or /bin/sh, depending on your version of Ubuntu.

    Option 2

    Easier option:

    SHELL=/bin/bash
    
    all:
        @echo a{3,4}
        @bash -c 'echo a{3,4}'
    

    This prints the same output twice unless you comment-out the SHELL= line

    Option 3

    If you can't/don't want to modify the make file, you can invoke it like so:

    make SHELL=/bin/bash
    

    beware of interactions with sub-makefiles or includes. You might want to look at the make -e option and the make export keyword: http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.html