nowox
nowox

Reputation: 29096

Dynamic include directive in a Makefile

Let's consider this Makefile:

.SUFFIXES:
.DEFAULT_GOAL := all

out=foo

clean: 
    rm -f vars.mk
    rm -f $(out)

vars.mk: vars.mk.default
    @echo "Regenerating $@..."
    cp $< $@ # Let's assume the translation is much complex than a cp

-include vars.mk

ifeq ($(filter foo,$(FOO)),)
    $(error FOO undefined)
endif

all: $(out)

$(out): vars.mk   
    echo "Cow says: I am not a $(FOO)." > $@

And the file vars.mk.default

FOO = foo bar

I would like to regenerate my targets if vars.mk.default is updated. Furthermore, as double check, one must check that foo exists in $(FOO).

How to force make to regenerate vars.mk if vars.mk.default is updated?

In other words, I would like this output:

$ make clean
$ sed 's/dog/cat/' vars.mk.default
$ make foo
Regenerating vars.mk...
echo "Cow says: I am not a cat" > all

$ make foo
make: Nothing to be done for 'all'.

$ sed 's/cat/dog/' vars.mk.default
$ make
Regenerating vars.mk...
echo "Cow says: I am not a dog" > all

$ rm vars.mak
$ make 
Regenerating vars.mk...
echo "Cow says: I am not a dog" > all

Upvotes: 0

Views: 692

Answers (3)

MadScientist
MadScientist

Reputation: 100856

To avoid failing if vars.mk doesn't exist, just check for it first:

ifeq ($(wildcard vars.mk),vars.mk)
  ifeq ($(filter foo,$(FOO)),)
    $(error FOO undefined)
  endif
endif

Upvotes: 2

John
John

Reputation: 3520

A couple of things. First, you should put a - in front of the include to prevent a warning from popping up if the file does not exist:

-include vars.mk

This will not cause a fatal error if vars.mk is not generated, but because the vars.mk rule would fail in this case, you would get your error from there.

You can then check if $(FOO) contains foo from within a recipe:

checkForFoo: vars.mk
    @[[ $(FOO) =~ .*foo.* ]] || false 

all:checkForFoo

The recipe is only run after the vars.mk was generated and included, so it should only fail in the conditions you want.

Upvotes: 0

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136286

My goal is to regenerate my targets if vars.mk.default is updated.

In this case make your targets depend on that file, but filter it out in the recipes, e.g.

foo.o : foo.cc vars.mk.default
    $(COMPILE) $(filter-out vars.mk.default,$^)

In the case vars.mk does not exist, make fails on the ifeq and do not generates vars.mk.

Make is going to build vars.mk and restart, see How Makefiles Are Remade for more details.

So, to avoid that error, check first if FOO is defined with ifdef FOO.

Upvotes: 1

Related Questions