1

I have a makefile that I want to be able to produce both a release build and a debug build. When I just run:

make 

I want the CXXFLAGS to be:

-std=c++11 -Isrc/includes -c -Os

and when I run

make debug

I want the CXXFLAGS to be

-std=c++11 -Isrc/includes -c -g

I am trying to do this through he use of phony targets and appending the extra flags to the CXXFLAGS variable, however these extra flags are never being appended. why is it that make debug still produces:

g++ -std=c++11 -Isrc/includes -c  src/file.cpp -o build/obj/file.o

and not the expected

g++ -std=c++11 -Isrc/includes -c -g src/file.cpp -o build/obj/file.o

when it is run?

contents of makefile:

vpath %.cpp src/macro
vpath %.cpp src/data_types
vpath %.hpp src/includes
vpath %.cpp src

CXX := g++
CXXFLAGS := -std=c++11 -Isrc/includes -c 
LXX = g++
LXXFLAGS := 

BUILDDIR := build
OBJDIR := $(BUILDDIR)/obj

SRCS := $(notdir $(shell find -name '*.cpp'))
OBJS := $(patsubst %.cpp, $(OBJDIR)/%.o, $(SRCS))

all: release aval

aval: builddir $(OBJS) $(SRCS) 
    $(LXX) $(LXXFLAGS) $(OBJS) -o $(BUILDDIR)/aval

$(OBJDIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) $^ -o $@

.PHONY: release
release: CXXFLAGS += -Os
release: LXXFLAGS += -s -Os

.PHONY: debug
debug:  clean db aval

.PHONY: db
db: CXXFLAGS += -g 


.PHONY: builddir
builddir:
    @mkdir -p $(OBJDIR)

.PHONY: clean
clean:
    @rm -f -r build/obj/*.o
    @rm -f build/avalanche
Chip
  • 129
  • 1
  • 12

2 Answers2

2

the issue with what you are doing is that you are editing the CXXFLAGS in the dependency list of a rule which won't work because of the way the make file is parsed.

Another way - and really easy, and saves you recursively calling make - which I don't see as particularly evil - but some do. Its certainly less complicated this way I find.

CXXFLAGS = defaults

ifneq (,$(findstring release,$(MAKECMDGOALS)))
  CXXFLAGS += release
else ifneq (,$(findstring debug,$(MAKECMDGOALS)))
  CXXFLAGS += debug
endif

all:
    @echo CXXFLAGS = $(CXXFLAGS)

# Rules for release / debug. The `; @:` part means the body of the rule is empty (do nothing). It just "calls" the dependency rule `all`.
release: all ; @:
debug: all ; @:

So here we are looking at the command goals and "parsing them" to look for your options and add to the flags.

We also need rules for debug and release to call the build rule (which I am calling all for the moment).

Here is the output:

admin@osboxes:~/sandbox/flags$ make
    CXXFLAGS = defaults
admin@osboxes:~/sandbox/flags$ make release
    CXXFLAGS = defaults release
admin@osboxes:~/sandbox/flags$ make debug
    CXXFLAGS = defaults debug
code_fodder
  • 15,263
  • 17
  • 90
  • 167
1

The approach you have chosen does not work, because

db: CXXFLAGS += -g

means that the variable CXXFLAGS is updated to include -g for the goal db, but no other goal. I.e. this change is not global like you intended it to be.


The following would be one way of implementing what you intended:

.PHONY: all release
# NOTE: must be first goal in Makefile to be default goal
all release:
    $(MAKE) -f $(lastword $(MAKEFILE_LIST)) BUILD_CXXFLAGS="-Os" BUILD_LXXFLAGS="-s -Os" build

.PHONY: debug
debug:
    $(MAKE) -f $(lastword $(MAKEFILE_LIST)) BUILD_CXXFLAGS="-g" BUILD_LXXFLAGS="-g" build

.PHONY: build
build: clean aval

CXX := g++
CXXFLAGS := $(BUILD_CXXFLAGS) -std=c++11 -Isrc/includes -c 
LXX = g++
LXXFLAGS := $(BUILD_LXXFLAGS)

# ... and the rest of your original Makefile ...

With build implemented as a dummy echo, I get the following output from the above:

$ make -s
CXX '-Os -std=c++11 -Isrc/includes -c' LXX '-s -Os'

$ make -s all
CXX '-Os -std=c++11 -Isrc/includes -c' LXX '-s -Os'

$ make -s release
CXX '-Os -std=c++11 -Isrc/includes -c' LXX '-s -Os'

$ make -s debug
CXX '-g -std=c++11 -Isrc/includes -c' LXX '-g'

BTW: you also need to add -g to LXXFLAGS, otherwise you won't get a debug binary.

Stefan Becker
  • 5,695
  • 9
  • 20
  • 30
  • i have put this in and it doesn't appear to be working. under build i have @echo $(CXXFLAGS) and it is outputting -std=c++11 -Isrc/includes -c when i run with make -s debug – Chip Feb 08 '19 at 15:16
  • never ming i see that this is because -g is set on LXXFLAGS that makes sense. – Chip Feb 08 '19 at 15:19
  • Sorry, I just noticed that there was a typo in my answer. Fixed. – Stefan Becker Feb 08 '19 at 15:25