Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I force a target to be rebuilt if a variable is set?

Assume I have a build-target foo:

foo:foo.c
    $(CC) $(CFLAGS) $(ARGS) -c foo.c -o foo

Now, ARGS is something that I pass on the command line:

$ make ARGS:=-DX=1 foo

So, I need to bypass make's cleverness, because the foo target does not only depend on which files have changed, but also on the value of ARGS.

Is there something in make to do this? My hack (see answer) doesn't seem to be the most elegant but it works. Anything better?

like image 567
bitmask Avatar asked Oct 01 '14 15:10

bitmask


People also ask

How do you force to recompile?

Use the command `make' to recompile the source files that really need recompilation. Make the changes in the header files. Use the command `make -t' to mark all the object files as up to date. The next time you run make, the changes in the header files do not cause any recompilation.

What does ?= Mean in Makefile?

?= indicates to set the KDIR variable only if it's not set/doesn't have a value. For example: KDIR ?= "foo" KDIR ?= "bar" test: echo $(KDIR)

What is Makefile target?

A simple makefile consists of “rules” with the following shape: target … : prerequisites … recipe … … A target is usually the name of a file that is generated by a program; examples of targets are executable or object files. A target can also be the name of an action to carry out, such as ' clean ' (see Phony Targets).


1 Answers

Here is a general solution to your specific problem.

You want to be able to depend on a variable as a prerequisite. That is, you can make it a prerequisite to any target in your makefile, and when the value of the variable changes, you rebuild those targets.

Here is a function that does that, you use this function to declare a variable to be dependable, and then you can use it as a prerequisite.

Note that if the variable is not used on the command line, it will still mean that variable still has a value, namely, the empty string.

define DEPENDABLE_VAR

.PHONY: phony
$1: phony
    @if [[ `cat $1 2>&1` != '$($1)' ]]; then \
        echo -n $($1) > $1 ; \
    fi

endef

#declare ARGS to be dependable
$(eval $(call DEPENDABLE_VAR,ARGS))


foo:foo.c ARGS
    $(CC) $(CFLAGS) $(ARGS) -c foo.c -o foo

In fact, we could omit the need for "declaration", and just write a similar function that will make all variables dependable by default. But I don't like that. I prefer that the users that modify makefiles I write, declare their intentions explicitly. It is good for them :)

like image 117
Mark Galeck Avatar answered Nov 22 '22 03:11

Mark Galeck