Change Makefile variable value inside the target body

MakefileTarget

Makefile Problem Overview


Is there a way to reassign Makefile variable value inside of the target body?

What I am trying to do is to add some extra flags for debug compilation:

%.erl: %.beam
    $(ERLC) $(ERLFLAGS) -o ebin $<

test: clean debug_compile_flag compile compile_test

debug_compile:
    $(ERLCFLAGS) += -DTEST

So if I invoke test target I would like to clean up my environment, add some new flags (like -DTEST to the existing ones), compile the whole code once again (first sources, then test modules).

I do not want to copy/paste the code for compiling with some new flags set since there is a lot of logic put here and there.

Is there some easy way to redefine the variable value so I can reuse the existing code?

Makefile Solutions


Solution 1 - Makefile

Yes, there is an easy way to do it, and without rerunning Make. Use a http://www.gnu.org/software/make/manual/make.html#Target_002dspecific">target-specific variable value:

test: clean debug_compile

debug_compile: ERLCFLAGS += -DTEST
debug_compile: compile compile_test;
    

Solution 2 - Makefile

Another answer is here: https://stackoverflow.com/questions/1909188/define-make-variable-at-rule-execution-time.

For the lazy, you can have rules like the following (FLAG and DEBUG are my variables):

.DBG:
    $(eval FLAG += $(DEBUG))

Solution 3 - Makefile

Here is the solution I use:

PASSWORD = abc123

main: sub
	@echo "in main" $(PASSWORD)

sub:
	@echo "in sub" $(PASSWORD)
	$(eval PASSWORD=qwerty)
	@echo "in sub" $(PASSWORD)

If you run make main then the output is:

in sub abc123
in sub qwerty
in main qwerty

You can see that the original value "abc123" is overwritten in the sub and the new value "qwerty" is visible at the main level.

Solution 4 - Makefile

To override on the command line try something like:

make prefix=<path to new dir> install

This won't change Makefile, but will alter the variable.

Solution 5 - Makefile

I wanted to add a target in a makefile to run tests, which implied recompiling the source code with some debug flags. Ian's answer: https://stackoverflow.com/a/15561911/ was the only solution that worked.

Here's the Makefile I came up with, which guaranties the order of execution when running make tests:

TARGET     = a.out

CC         = g++
GENERIC_F  = -Wall -Wextra -I. -Idoctest/doctest/

CFLAGS     = -O0 -std=c++11 $(GENERIC_F)
DEBUG_MODE = -DDEBUG

LINKER     = g++
LFLAGS     = $(GENERIC_F) -lm

SRCDIR     = src
OBJDIR     = build
BINDIR     = bin

SOURCES    = $(wildcard $(SRCDIR)/*.cc)
INCLUDES   = $(wildcard $(SRCDIR)/*.h)
OBJECTS    = $(SOURCES:$(SRCDIR)/%.cc=$(OBJDIR)/%.o)
rm         = rm -f

.PHONY: clear_screen tests extend_cflags

$(BINDIR)/$(TARGET): $(OBJECTS) $(INCLUDES)
	$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
	@echo -e "Linking complete!\n"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cc $(INCLUDES)
	@mkdir -p $(OBJDIR) $(BINDIR)
	$(CC) $(CFLAGS) -c $< -o $@
	@echo -e "Compiled "$<" successfully!\n"

.PHONY: clean
clean:
	@$(rm) $(OBJECTS)
	@echo "Cleanup complete!"

.PHONY: remove
remove: clean
	@$(rm) $(BINDIR)/$(TARGET)
	@echo "Executable removed!"

clear_screen:
	@clear

extend_cflags:
	$(eval CFLAGS += $(DEBUG_MODE))

tests: | remove extend_cflags $(BINDIR)/$(TARGET) clear_screen
	@$(BINDIR)/$(TARGET)

Solution 6 - Makefile

Edit: As explained by Beta in the other answer, it is possible.


No. There is no way to do this in the Makefile. You can however change the value of a variable on the make command line. If you rewrite your Makefile as follows:

ERLCFLAGS += $(ERLCFLAGSADDED)

%.erl: %.beam
    $(ERLC) $(ERLCFLAGS) -o ebin $<

test: clean compile compile_test

Then, you can invoke make to perform your tests using:

make ERLCFLAGSADDED=-DTEST test

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpaulgrayView Question on Stackoverflow
Solution 1 - MakefileBetaView Answer on Stackoverflow
Solution 2 - MakefileIan OoiView Answer on Stackoverflow
Solution 3 - MakefileCsongor HalmaiView Answer on Stackoverflow
Solution 4 - Makefileplacid chatView Answer on Stackoverflow
Solution 5 - MakefileAlberto ChiusoleView Answer on Stackoverflow
Solution 6 - MakefileDidier TrossetView Answer on Stackoverflow