C/C++ Projects

Read time: 3 minutes (858 words)

My recommended structure for C/C++ projects puts most code in a lib subdirectory. In order to separate major project components, you can create subdirectories under lib. However, doing so introduces a problem if we want make to find source files automatically. To solve this problem, I use another simple Python script to search for code files.

This script recursively searched under the named directory for all files ending with a specified extension:

mk/pyfind.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import os
import sys

dir = sys.argv[1]
ext = sys.argv[2]
result = []
for root, dirs, files in os.walk(dir):
    for name in files:
        if name.endswith(ext):
            result.append(os.path.join(root,name))

print(" ".join(result));


Here is the Makefile` component that uses this script:

mk/cppproj.mk
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
HDRS	:= $(shell python mk/pyfind.py include .h)

USRCS	:= $(wildcard src/*.cpp)
LSRCS	:= $(shell python mk/pyfind.py lib .cpp)
TSRCS	:= $(wildcard tests/*.cpp)
SRCS    := $(USRCS) $(LSRCS) $(TSRCS)

UOBJS   := $(USRCS:.cpp=.o)
LOBJS   := $(LSRCS:.cpp=.o)
TOBJS   := $(TSRCS:.cpp=.o)
OBJS    := $(UOBJS) $(LOBJS) $(TOBJS)
ifeq ($(PLATFORM), Windows)
	DOBJS = $(subst /,\,$(OBJS))
else
	DOBJS = OBJS
endif


CXXFLAGS	:= -std=c++11 -Iinclude

.PHONY: all
all: $(TARGET) ## build application (default)

$(TARGET):	$(UOBJS) $(LOBJS)
	$(CXX) -o $@ $^ $(LFLAGS)

%.o:	%.cpp
	$(CXX) -c -o $@ $< $(CXXFLAGS)

.PHONY: clean ## remove all build artifacts
	$(DEL) $(DOBJS)

This script searches all subdirectories under the named directory for files ending with the indicated extension. It then builds another list of object files. There is one trick that gets a list of object files using the standard Windows backslah path separater. This is needed so the del command will work properly when we set up a clean target on a PC.