Home > Back-end >  Using command substituition in Makefiles
Using command substituition in Makefiles

Time:09-13

In the Linux sh/bash shell, I can get Linux user ID with UID_CODE=$(id -u):$(id -g). It usually gives UID_CODE=1000:1000

However, I'm writing a Makefile, similar to this:

run:
UID_CODE=$(id -u):$(id -g) ./a.out

The Makefile gives UID_CODE=: which is just the :

I did some digging and found I need to use $$, but $$(id -u):$$(id -g) gives me UID_CODE=$(id -u):$(id -g)

How do I get the same result as in the shell?

CodePudding user response:

Here's a sample makefile setting a variable and passing it via the environment to an external program in a rule (you can use ${...} or $(...)):

$ cat Makefile.mk
FOO := "foo: $(shell id -g):$(shell id -u)"

tst:
    echo "testing: $(FOO)"
    FOO=${FOO} ./a.out

This is using the GNU makefile feature of $(shell ...), but you're probably using GNU make so that shouldn't be a problem.

CodePudding user response:

This will definitely work and is probably the best way to do this unless you need it to be done in lots and lots of rules:

run:
    UID_CODE=$$(id -u):$$(id -g) ./a.out

There's not really a good reason to use GNU make-specific features like the shell function here.

I'm not sure what you mean when you say: gives me UID_CODE=$(id -u):$(id -g) Do you mean, that's what make prints out? Yes, that's fine. make is printing out the shell command that it will run, just as you would type it into your shell prompt.

When the shell runs that command it will expand the $(id -u) and replace it with the right UID. For example you can test this:

run:
    UID_CODE=$$(id -u):$$(id -g) env | grep UID_CODE

Running make here will print the following:

UID_CODE=$(id -u):$(id -g) env | grep UID_CODE
UID_CODE=1000:1000

(or whatever your UID/GID values are). The first line is make showing you the command it will run, and the second line is the output of the command showing that UID_CODE is set as you expect.

  • Related