Search code examples
makefilegnu-make

Make - Override variables with something like dotenv


Just started using Makefile and I have been make a heavily use of the capability of overriding variables through args. But sometime I have to override three or more and becomes a little annoying.

So my question is: Does Make has a built-in functionality to source a plain text file and override some variable? (like we do with dotenv libraries)

The only way I was able to accomplish this is to create an internal IF/ELSE IF/ELSE block controlled by (for example) a variable named env. It works fine but I do feel it makes to whole Makefile unnecessarily bloated.

Thanks.


Solution

  • It's not really clear what you are looking for, but you can do something like adding this to the very end of your makefile:

    include $(wildcard local.mk)
    

    Then if the file local.mk exists it will be included and any variables in it will be in effect when the recipes are invoked (because they were set last).

    However, this will have problems if you've already used those variables in an immediate context previously. For example, if you have:

    FOO = foo
    MYVAR := $(FOO)
    
    all: ; @echo $(MYVAR)
    
    include $(wildcard local.mk)
    

    where local.mk contains FOO = bar, this won't help because MYVAR was set to the value of FOO before the include file was referenced.

    Another option is to put the include first, then be careful to always use ?= instead of = so that variables preserve existing values:

    include $(wildcard local.mk)
    
    FOO ?= foo
    MYVAR := $(FOO)
    
    all: ; @echo $(MYVAR)
    

    will work but if you forget and use FOO = foo then your local variables won't be in effect.

    One other option, if you're worried about this, would be to use override in your local.mk; if it contains override FOO = bar then the second method above (include first) will work even if you reset FOO inside the makefile that setting will be ignored. But, if you do this then you can't also override this value on the command line.

    One last option, if you don't want to change your makefile, is to use -f on the make command line to load the local makefile. For example, run make -f local.mk -f Makefile to load local.mk first; this is the equivalent of (and has the same behavior as) adding the include at the start.