Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using curly brackets for variable expansion in makefile doesn't work

When I run below command on shell, it works properly. but if I write it in a Makefile and call it with "make" command it doesn't work.

cp wpa_{cli,supplicant,passphrase,event} /usr/local/bin/

error after "make" command:

cp: cannot stat `wpa_{cli,supplicant,passphrase,event}': No such file or directory

What can i do to make it work with Makefile? I use Ubuntu 12.04. Same Makefile works on other linux distributions.

like image 276
Necip Onur Uzun Avatar asked Oct 11 '12 11:10

Necip Onur Uzun


People also ask

What is $$ in Makefile?

Double dollar sign If you want a string to have a dollar sign, you can use $$ . This is how to use a shell variable in bash or sh . Note the differences between Makefile variables and Shell variables in this next example.

What are {} used for in bash?

Bash brace expansion is used to generate stings at the command line or in a shell script. The syntax for brace expansion consists of either a sequence specification or a comma separated list of items inside curly braces "{}". A sequence consists of a starting and ending item separated by two periods "..".

What does curly brackets do in C++?

In programming, curly braces (the { and } characters) are used in a variety of ways. In C/C++, they are used to signify the start and end of a series of statements. In the following expression, everything between the { and } are executed if the variable mouseDOWNinText is true.

What does curly brackets mean in shell script?

The end of the variable name is usually signified by a space or newline. But what if we don't want a space or newline after printing the variable value? The curly braces tell the shell interpreter where the end of the variable name is.


2 Answers

Make uses old-school Bourne shell (/bin/sh) by default which does not support brace expansion. Set the SHELL variable in your makefile to /bin/bash if it's not already set.

Just add a line in the top of your makefile with:

SHELL=/usr/bin/bash

(please confirm your bash path).

like image 91
Steve K Avatar answered Sep 20 '22 13:09

Steve K


As Steve K explains, it's a bashism. If you want to stick more closely to the standard, you can use a for loop without too much trouble.

for x in cli supplicant passphrase event; do cp -v wpa_$$x /usr/local/bin/; done

As usual for makefiles, put it all on one line or use backslashes to break it into a few lines. The double dollar sign indicates that make needs to pass the $ to the shell.

like image 32
bk. Avatar answered Sep 17 '22 13:09

bk.