How do I use shell variables in Makefile actions? How do I use shell variables in Makefile actions? bash bash

How do I use shell variables in Makefile actions?


There are at least two considerations. $() references a Make variable. You must escape the $ to do command substitution. Also, the shell commands must be all on one line. Try:

exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM \    pg_database WHERE datname='the_db'"); \    if [ "$$exists" -eq 1 ]; then \        dropdb the_db; \    fi; \    createdb -E UTF8 the_db

On the other hand, it seems like it would be simpler to just always try to drop the database, and allow failure:

rebuilddb:    -dropdb the_db  # Leading - instructs make to not abort on error    createdb -E UTF8 the_db


For completness the usage in $(eval $(call ...)

The usage in dynamic generation rules you have to escape the shell variables with $$$$.

Here is an example which has been tested with "GNU Make 4.2.1":

MY_LIBS=a b c

a_objs=a1.o a2.o
b_objs=b1.o b2.o b3.o
c_objs=c1.o c2.o c3.o c4.o

default: libs

# function lib_rule(name, objs)

define lib_rule
lib$(1).a: $(2)
exit 1 | tee make.log ; test $$$${PIPESTATUS[0]} -eq 0
endef

# generate rules
$(foreach L,$(MY_LIBS),$(eval $(call lib_rule,$(L),$($(L)_objs))))

# call generated rules
libs: $(patsubst %,lib%.a,$(MY_LIBS))

# dummy object generation
%.o:%.c
touch $@

# dummy source generation
%.c:
touch $@

clean::
rm -f *.c *.o lib*.a make.log

The output: 'make -Rr'

exit 1 | tee make.log ; test ${PIPESTATUS[0]} -eq 0
make: *** [Makefile:18: liba.a] Error 1

Result of last command in pipe is true from tee. You can see bash variable PIPESTATUS[0] has the value false from exit 1

Watch the Database: 'make -Rrp'

define lib_rule
lib$(1).a: $(2)
exit 1 | tee make.log ; test $$$${PIPESTATUS[0]} -eq 0
endef

...

libc.a: c1.o c2.o c3.o c4.o
exit 1 | tee make.log ; test $${PIPESTATUS[0]} -eq 0