Magyar_57
Magyar_57

Reputation: 57

How to unconditionnally re-assign a variable in a makefile (with submakefile)?

I am trying to re-assign a makefile variable (depending on its initial value), while keeping the new value in a submakefile. Here is the layout:

Makefile
subdir/
    - Makefile-sub

Main makefile:

export ARCH:=good_value
all:
    @echo In main makefile, ARCH=$(ARCH)
    @make --no-print-directory -C subdir

Sub-makefile:

all:
    @echo In sub makefile, ARCH=$(ARCH)

If I run make, I get the expected output:

In main makefile, ARCH=good_value
In sub makefile, ARCH=good_value

But if I try to override the variable from the CLI (which I need to be able to do), it doesn't work anymore: make ARCH=bad_value yields

In main makefile, ARCH=bad_value
In sub makefile, ARCH=bad_value

And make -E ARCH=bad_value or make -E "ARCH=bad_value" or make -E "ARCH:=bad_value" or make -E "export ARCH=bad_value" or make -E "export ARCH:=bad_value" yields

In main makefile, ARCH=good_value
In sub makefile, ARCH=bad_value

I noticed that calling the makefile as @make --no-print-directory -C subdir ARCH=$(ARCH) reassigns the value correctly, but I reckon I shouldn't need to do it, and I'd rather avoid it since I have a LOT of variables to reassign, and sub-sub-makefiles. Is there another solution to my problem ?

Upvotes: 1

Views: 37

Answers (1)

Renaud Pacalet
Renaud Pacalet

Reputation: 29290

You could use 3 sets of variables:

  • DEFAULT_VAR to define the default value of variable VAR,
  • TOP_VAR to be used in the top Makefile instead of VAR,
  • VAR to be used in sub-Makefiles.

This would imply modifications of your top Makefile but only to this one (replace all uses of ARCH with TOP_ARCH):

$ cat Makefile
TOP_ARCH := good_value
export ARCH := good_value

all:
    @echo In main makefile: TOP_ARCH=$(TOP_ARCH)
    $(MAKE) --no-print-directory -C subdir

$ cat subdir/Makefile
all:
    @echo In sub makefile: ARCH=$(ARCH)

$ make
In main makefile: TOP_ARCH=good_value
make --no-print-directory -C subdir
In sub makefile: ARCH=good_value

$ make TOP_ARCH=bad_value
In main makefile: TOP_ARCH=bad_value
make --no-print-directory -C subdir
In sub makefile: ARCH=good_value

If you have many such variables and your make is GNU make you can automate most of this:

$ cat Makefile
VARIABLES := ARCH BIN COMP
DEFAULT_ARCH := good_value
DEFAULT_BIN := good_value
DEFAULT_COMP := good_value
$(foreach v,$(VARIABLES),$(eval TOP_$v=$(DEFAULT_$v)$(eval export $v=$(DEFAULT_$v))))

all:
    @echo In main makefile:$(foreach v,$(VARIABLES), TOP_$v=$(TOP_$v))
    $(MAKE) --no-print-directory -C subdir

$ cat subdir/Makefile
all:
    @echo In sub makefile:$(foreach v,ARCH BIN COMP, $v=$($v))

$ make TOP_ARCH=bad_value TOP_COMP=bad_value
In main makefile: TOP_ARCH=bad_value, TOP_BIN=good_value, TOP_COMP=bad_value
make --no-print-directory -C subdir
In sub makefile: ARCH=good_value, BIN=good_value, COMP=good_value

Upvotes: 1

Related Questions