Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle shell expansions in GNU Make under Ubuntu?

Tags:

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?

like image 487
Adam Lindberg Avatar asked Jul 13 '11 15:07

Adam Lindberg


People also ask

Which shell does make use?

By default make uses the /bin/sh shell. The default can be over ridden by using the variable SHELL = /bin/sh or equivalent to use the shell of your preference. This variable should be included in every descriptor file to make sure the same shell is used each time the descriptor file is executed.

What is shell in Makefile?

$(shell) is a special function in gmake that runs an external command and captures the output for use in the makefile. For example, you could get the current working directory like this: CWD=$(shell pwd) all: @echo This makefile lives in $(CWD).

How do I run a command in Makefile?

@anon58192932 That specific iteration, to execute a command, is usually done in a shell syntax fragment in a build recipe, so it occurs in the shell, rather than in make: for x in $(FILES); do command $$x; done . Note the doubled up $$ which passes a single $ to the shell.

What is $$ in Makefile?

$$ means be interpreted as a $ by the shell. the $(UNZIP_PATH) gets expanded by make before being interpreted by the shell.


1 Answers

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

like image 92
sehe Avatar answered Sep 20 '22 15:09

sehe