HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Makefile to build and debug a C++ console app

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
makefileappdebugandconsolebuild

Problem

I had to create this makefile to build and debug a C++ console app. I just need some hints and tips on how I can organize my makefile.

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=helloWorld.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=helloWorld

all: $(SOURCES) $(EXECUTABLE)

debug: CXXFLAGS += -DDEBUG -g
debug: CCFLAGS += -DDEBUG -g
debug: helloWorld

clean:
    rm *o helloWorld

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) %%CODEBLOCK_0%%lt; -o $@

Solution

-
Making sources?

The line

all: $(SOURCES) $(EXECUTABLE)


asks make to build $(SOURCES), in this case helloWorld.cpp. Is it possible to build it? Strictly speaking there are situations when you do want to build the source file (e.g. fetch it from git/cvs/sccs) but it is not applicable here: no rule is provided. Generally you don't want to build something which doesn't depend on anything. In any case, let make deduce; this is what it is good for.

all: $(EXECUTABLE)


is what you want.

-
Be consistent

all depends on $(EXECUTABLE), but debug depends on helloWorld. Once you defined a macro, use it everywhere.

-
Synonymous targets

Consider the scenario: make; ./helloWold; something goes wrong and you want to debug; make debug: everything is up to date. To have a debug build you must intervene with make clean. A good practice is to separate debug and release builds into different directories.

-
Automatic dependencies

In your example the .o file depends only on a corresponding .cpp. In real life the .cpp has some #includes - and the .o must depend on them all. Otherwise you will end up with an inconsistent build. Listing the .h dependencies manually is tedious and error prone. The standard practice is to let the compiler generate them automatically. For example, g++ has -MM, -MT, etc options just for this purpose:

DEPS := $(SOURCES:.cpp=.d)
.cpp.d:
    $(CC) $(CXXFLAGS) -MM -MT -o $@ %%CODEBLOCK_2%%lt;
-include $(DEPS)


-
-c doesn't belong to CFLAGS

-c is typically not listed in a CFLAGS: you may want to generate various outputs (e.g. preprocessed source, assembly source, dependencies, documentation, etc) with the same set of flags. The way to achieve this is to specify -c or -MM or -S or whatever separately from other flags, e.g.

.cpp.o:
    $(CC) -c $(CFLAGS) ....

.cpp.s:
    $(CC) -S $(CFLAGS) ....


etc.

-
CC

Traditionally a c++ compiler is referred as CXX and uses CXXFLAGS. The CC and CFLAGS are reserved for plain c.

Code Snippets

all: $(SOURCES) $(EXECUTABLE)
all: $(EXECUTABLE)
DEPS := $(SOURCES:.cpp=.d)
.cpp.d:
    $(CC) $(CXXFLAGS) -MM -MT -o $@ $<
-include $(DEPS)
.cpp.o:
    $(CC) -c $(CFLAGS) ....

.cpp.s:
    $(CC) -S $(CFLAGS) ....

Context

StackExchange Code Review Q#115673, answer score: 7

Revisions (0)

No revisions yet.