Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile set variable in target

Tags:

makefile

I have a makefile where a variable $DEBUG decides whether to build for deployment or debugging. There is one main Makefile, and multiple platform-specific makefiles that get included. I want the variable $DEBUG to be set to 1 automatically when the target test is built.

The main makefile:

DEBUG := 0

test : override DEBUG := 1

DIST_DIR := dist/
ifeq ($(DEBUG), 1)
    BUILD_DIR := build/debug
else
    BUILD_DIR := build/deploy
endif


# detect operating system
ifeq ($(OS), Windows_NT)
    UNAME := Windows
else
    UNAME := $(shell uname -s)
endif

# include platform-specific Makefile
export
ifeq ($(UNAME), Darwin)
    include Makefile.darwin
endif
ifeq ($(UNAME), Linux)
    include Makefile.linux
endif

And the platform-specific Makefile.linux:

... 
CXX := clang++-3.8
CXXFLAGS := -std=c++14 -fPIC -I./external/include -fcolor-diagnostics
LDFLAGS := 
LDLIBS := -lpthread -lm


ifeq ($(DEBUG), 1)
    CXXFLAGS += -g
else
    CXXFLAGS += -O3 -DNDEBUG
endif

... 

all : $(TARGET)


test : $(TEST_TARGET)
    $(TEST_TARGET)

So there are two rules for test: One in the main makefile sets the target-specific variable $DEBUG, and the one in Makefile.linux builds the test. The variables used for building ($CXXFLAGS, $BUILDDIR, and others) are set before the rules, and use conditionals.

Everything in the makefiles is working correctly, however calling make test does not alter the variable $DEBUG: both $CXXFLAGS and $BUILDDIR still get set to the values they would have for a deployment built.

Is there a way to first set $DEBUG := 1 in Makefile when the target is test, and then normally proceed? Or is there a special variable that contains the target name, for example

ifeq ($(MAKEFILE_TARGET), test)
    ...
endif
like image 972
tmlen Avatar asked Mar 23 '16 09:03

tmlen


1 Answers

test : override DEBUG := 1 doesn't work because it declares a target-specific variable that is only visible within that recipe.

There does exist a variable containing the target names that were specified at the command line: MAKECMDGOALS. Note that it doesn't include the default target if it wasn't explicitly specified at the command line.

Example makefile:

DEBUG := $(filter test,$(MAKECMDGOALS))

all:
    @echo all : $(MAKECMDGOALS) : $(DEBUG) : $(if $(DEBUG),1,0)

test:
    @echo test : $(MAKECMDGOALS) : $(DEBUG) : $(if $(DEBUG),1,0)

Usage:

$ make
all : : : 0
$ make all
all : all : : 0
$ make test
test : test : test : 1
$ make all test
all : all test : test : 1
test : all test : test : 1
like image 110
Ray Avatar answered Sep 23 '22 01:09

Ray