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

Makefile and directory structure

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

Problem

I am looking for improvements for this basic makefile and directory structure. I know this is overkill and could be compiled with one line in a flat directory structure, but I want to use this as a learning exercise.

CC=g++
CFLAGS=-Wl,--no-as-needed -std=c++11 
LIBS=-lpthread
SRC=$(PWD)/src
BUILDDIR=$(PWD)/build
OUTDIR=$(BUILDDIR)/bin
TEMPDIR=$(BUILDDIR)/tmp
MKDIR_P = mkdir -p

.PHONY: directories clean run

all: directories $(OUTDIR)/terminal

$(OUTDIR)/terminal: $(TEMPDIR)/main.o $(TEMPDIR)/terminal.o
    $(CC) $(CFLAGS) $(TEMPDIR)/terminal.o $(TEMPDIR)/main.o $(LIBS) -o $(OUTDIR)/terminal

$(TEMPDIR)/main.o: $(SRC)/main.cpp $(SRC)/terminal.hpp
    $(CC) -c $(CFLAGS) $(SRC)/main.cpp -o $(TEMPDIR)/main.o

$(TEMPDIR)/terminal.o: $(SRC)/terminal.cpp $(SRC)/terminal.hpp
    $(CC) -c $(CFLAGS) $(SRC)/terminal.cpp -o $(TEMPDIR)/terminal.o

directories: ${OUTDIR} $(TEMPDIR)

$(OUTDIR): 
    ${MKDIR_P} $(OUTDIR)

$(TEMPDIR):
    ${MKDIR_P} $(TEMPDIR)

clean:
    rm -rf $(BUILDDIR)

run:
    $(OUTDIR)/terminal

Solution

-
Stem rules:

Spelling out compilation rule for each object file is tedious and error prone.

$(TEMPDIR)/%.o: $(SRC)/%.c
    $(CXX) $(CFLAGS) -c %%CODEBLOCK_0%%lt; -o $@


takes care about all of them.

-
Autodependencies:

Spelling out dependencies for each object file is tedious and error prone. gcc can do it for you:

$(TEMPDIR)/main.d: $(SRC)/main.c
    $(CXX) $(CFLAGS) -MM -MT %%CODEBLOCK_1%%lt; -o $@

-include $(TEMPDIR)/main.d


Of course you we don't want to spell it out for each source file, which naturally leads us to the next step.

-
Use macros. Shall you add more source files, only FILES needs to be modified.

FILES = main.c terminal.c
SOURCES = $(patsubst %,$(SRC)/%,$(FILES))
OBJECTS = $(patsubst %.c,$(TEMPDIR)/%.o,$(FILES))
DEPS    = $(patsubst %.c.$(TEMPDIR)/%.d,$(FILES))

$(TEMPDIR)/%.o: $(SRC)/%.c
    $(CXX) $(CFLAGS) -c %%CODEBLOCK_2%%lt; -o $@

$(TEMPDIR)/%.d: $(SRC)/%.c
    $(CXX) $(CFLAGS) -MM -MT %%CODEBLOCK_2%%lt; -o $@

-include $(DEPS)

$(TARGET): $(OBJECTS)
    $(CXX) $(LDFLAGS) $(OBJECTS) -o $(TARGET)

Code Snippets

$(TEMPDIR)/%.o: $(SRC)/%.c
    $(CXX) $(CFLAGS) -c $< -o $@
$(TEMPDIR)/main.d: $(SRC)/main.c
    $(CXX) $(CFLAGS) -MM -MT $< -o $@

-include $(TEMPDIR)/main.d
FILES = main.c terminal.c
SOURCES = $(patsubst %,$(SRC)/%,$(FILES))
OBJECTS = $(patsubst %.c,$(TEMPDIR)/%.o,$(FILES))
DEPS    = $(patsubst %.c.$(TEMPDIR)/%.d,$(FILES))

$(TEMPDIR)/%.o: $(SRC)/%.c
    $(CXX) $(CFLAGS) -c $< -o $@

$(TEMPDIR)/%.d: $(SRC)/%.c
    $(CXX) $(CFLAGS) -MM -MT $< -o $@

-include $(DEPS)

$(TARGET): $(OBJECTS)
    $(CXX) $(LDFLAGS) $(OBJECTS) -o $(TARGET)

Context

StackExchange Code Review Q#77157, answer score: 7

Revisions (0)

No revisions yet.