From: Olivier Scalbert on
Hello,

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
From: Rainer Weikusat on
Olivier Scalbert <olivier.scalbert(a)algosyn.com> writes:
> 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.

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).
From: Olivier Scalbert on
Rainer Weikusat wrote:

> 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
From: Maxim Yegorushkin on
On 14/12/09 09:43, Olivier Scalbert wrote:

[]

> 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
From: Maxim Yegorushkin on
On 09/12/09 12:31, Olivier Scalbert wrote:
> Hello,
>
> 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

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