I am doing a small project and I have some difficulties to create the
makefile.
I want to be able to create a debug and a release version, so I have
different directories for the generated object files.
The following makefile seems to work but I am sure it can be simplified
a lot. I have done some experiments but without any success ...
If you can help me, I would appreciate !
Olivier
SRC_DIR = src
DEBUG_OBJ_DIR = objdbg
DEBUG_FLAGS = -g -Wall -pedantic
RELEASE_OBJ_DIR = obj
RELEASE_FLAGS = -O3 -Wall -pedantic
all: debug release
debug: prog-dbg
release: prog
$(DEBUG_OBJ_DIR)/main.o: $(SRC_DIR)/main.cc
g++ -c $(DEBUG_FLAGS) $< -o $@
$(DEBUG_OBJ_DIR)/engine.o: $(SRC_DIR)/engine.cc
g++ -c $(DEBUG_FLAGS) $< -o $@
prog-dbg: $(DEBUG_OBJ_DIR)/engine.o $(DEBUG_OBJ_DIR)/main.o
g++ $^ -o $@
$(RELEASE_OBJ_DIR)/main.o: $(SRC_DIR)/main.cc
g++ -c $(RELEASE_FLAGS) $< -o $@
$(RELEASE_OBJ_DIR)/engine.o: $(SRC_DIR)/engine.cc
g++ -c $(RELEASE_FLAGS) $< -o $@
prog: $(RELEASE_OBJ_DIR)/engine.o $(RELEASE_OBJ_DIR)/main.o
g++ $^ -o $@
clean:
rm -f $(RELEASE_OBJ_DIR)/*
rm -f $(DEBUG_OBJ_DIR)/*
rm -f prog-dbg prog
I usually do this by passing a command-line parameter to make when I
want a non-debug build ('releases' are much less frequent than
'internal builds') and use a different set of compiler flags (via GNU
make conditionals and a variable) if this parameter was
given. Additionally, I use a variable to hold the extension for object
code files and 'debug build files' end with .o while 'release build
files' use .o2 instead (which gets around the need to use different
directories).
> I usually do this by passing a command-line parameter to make when I
> want a non-debug build ('releases' are much less frequent than
> 'internal builds') and use a different set of compiler flags (via GNU
> make conditionals and a variable) if this parameter was
> given. Additionally, I use a variable to hold the extension for object
> code files and 'debug build files' end with .o while 'release build
> files' use .o2 instead (which gets around the need to use different
> directories).
Thanks for the help !
By the way, do you know a news group specialized in make and Makefiles ?
I try to google but I found nothing ...
Olivier
[]
> By the way, do you know a news group specialized in make and Makefiles ?
> I try to google but I found nothing ...
gmane.comp.gnu.make.general it is.
--
Max
You can simplify this in many interesting ways using GNU Make. (I see no
reason to use any other make).
Something along these lines:
# override with `make BUILD=release`
# default to debug build
BUILD := debug
SRC_DIR = :src
# using make's computed variables to select object and bin folders
# depending on the build type
OBJ_DIR.debug := objdbg
OBJ_DIR.release : objrel
OBJ_DIR := $(OBJ_DIR.$(BUILD))
BIN_DIR.debug := bindbg
BIN_DIR.release := binrel
BIN_DIR := $(BIN_DIR.$(BUILD))
# same for flags
FLAGS.debug = -g -Wall -pedantic
FLAGS.release = -g -O3 -Wall -pedantic # can have debuginfo with -O
FLAGS := $(FLAGS.$(BUILD))
all: $(BIN_DIR)/prog
# how to build any .o from the corresponding.cc
# the | order-only dependency is to create OBJ_DIR on demand
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cc | $(OBJ_DIR)
g++ -c $(FLAGS) $< -o $@
# the | order-only dependency is to create BIN_DIR on demand
$(BIN_DIR)/prog: $(OBJ_DIR)/engine.o $(OBJ_DIR)/main.o | $(BIN_DIR)
g++ $^ -o $@
# how to create folders on demand
$(OBJ_DIR) $(BIN_DIR):
mkdir $@
clean :
rm -rf $(OBJ_DIR) $(BIN_DIR)
.PHONY: clean
This makefile builds or cleans only one type of the build depending on
the invocation. To clean and build a debug build invoke make as:
make clean
make
To clean and build a release build invoke as:
make BUILD=release clean
make BUILD=release
--
Max
Thanks Maxim !
Olivier