Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make targets depend on variables

I want (GNU) make to rebuild when variables change. How can I achieve this?

For example,

$ make project
[...]
$ make project
make: `project' is up to date.

...like it should, but then I'd prefer

$ make project IMPORTANTVARIABLE=foobar
make: `project' is up to date.

to rebuild some or all of project.

like image 958
tiwo Avatar asked Jul 25 '12 10:07

tiwo


People also ask

What is a make target?

A 'make target' is basically a file that you want rebuilt. Make can't divine what you want built, so you have to tell it, implicitly or explicitly, what it should build.

What is $@ in makefile?

$@ is the name of the target being generated, and $< the first prerequisite (usually a source file). You can find a list of all these special variables in the GNU Make manual.

What is automatic variables in makefile?

Within the context of an individual rule, Make automatically defines a number of special variables. These variables can have a different value for each rule in a makefile and are designed to make writing rules simpler. These variables can only be used in the recipe portion of a rule. Variable.

Can a target have dependencies on other targets?

Targets can have dependencies on other targets. For example, a target for deployment depends on a target for compilation. The MSBuild engine executes dependencies in the order in which they appear in the DependsOnTargets attribute, from left to right. For more information, see Targets.

Can the target variable change depending on the problem statement?

We understood that our target variable can change depending on the problem statement. We saw the importance of defining different thresholds on the probability models to maximize our business goal. We made an applied case to understand better how to apply this in a real context. That’s all for today, folks.

What should be the default target for compiling a program?

Compile the entire program. This should be the default target. This target need not rebuild any documentation files; Info files should normally be included in the distribution, and DVI (and other documentation format) files should be made only when explicitly asked for.

How to add a target with no output file?

The target has no output file and is always considered out of date even if the commands try to create a file with the name of the target. Use the add_custom_command () command to generate a file with dependencies. By default nothing depends on the custom target. Use the add_dependencies () command to add dependencies to or from other targets.


2 Answers

Make wasn't designed to refer to variable content but Reinier's approach shows us the workaround. Unfortunately, using variable value as a file name is both insecure and error-prone. Hopefully, Unix tools can help us to properly encode the value. So

IMPORTANTVARIABLE = a trouble

# GUARD is a function which calculates md5 sum for its
# argument variable name. Note, that both cut and md5sum are
# members of coreutils package so they should be available on
# nearly all systems.
GUARD = $(1)_GUARD_$(shell echo $($(1)) | md5sum | cut -d ' ' -f 1)

foo: bar $(call GUARD,IMPORTANTVARIABLE)
    @echo "Rebuilding foo with $(IMPORTANTVARIABLE)"
    @touch $@

$(call GUARD,IMPORTANTVARIABLE):
    rm -rf IMPORTANTVARIABLE*
    touch $@

Here you virtually depend your target on a special file named $(NAME)_GUARD_$(VALUEMD5) which is safe to refer to and has (almost) 1-to-1 correspondence with variable's value. Note that call and shell are GNU Make extensions.

like image 128
grwlf Avatar answered Oct 13 '22 02:10

grwlf


You could use empty files to record the last value of your variable by using something like this:

someTarget: IMPORTANTVARIABLE.$(IMPORTANTVARIABLE)
    @echo Remaking $@ because IMPORTANTVARIABLE has changed
    touch $@

IMPORTANTVARIABLE.$(IMPORTANTVARIABLE):
    @rm -f IMPORTANTVARIABLE.*
    touch $@

After your make run, there will be an empty file in your directory whose name starts with IMPORTANTVARIABLE. and has the value of your variable appended. This basically contains the information about what the last value of the variable IMPORTANTVARIABLE was.

You can add more variables with this approach and make it more sophisticated using pattern rules -- but this example gives you the gist of it.

like image 33
Reinier Torenbeek Avatar answered Oct 13 '22 02:10

Reinier Torenbeek