A simple way to write Makefile C mixed with C + +

Keywords: Makefile Linux

After using Linux for a long time, I still feel that I am not familiar with Makefile. I often struggle for Makefile of a more complex project for half a day. Now make a summary of the basic writing method of Makefile for future reference.

Here I use a Makefile that I wrote recently to explain. It's a mixed project of C and C + +. A complete Makefile is attached.

The directory structure is:

+--include/
+--include/librtmp
+--liblog/
+--librtmp/
+--release/
+--release/liblog
+--release/librtmp
+--xx.cpp
+--Makefile

Explanation:

TARGET: TARGET file
 Obj? Dir? This: intermediate file storage directory
 COMPILE.cpp and COMPILE.c: compile
 LINK.cpp and LINK.c: links
 SOURCE_PATHS: source code. c and. cpp storage directory, multiple directories separated by spaces
 Include? Paths: folder. h holds directories separated by spaces
 foreach: used to traverse multiple directories
 wildcard: the specified file used to traverse the specified directory
 Relobjfiles? cpp and relobjfiles? c: corresponding. o files after. cpp and. c are compiled

When making, you will first execute COMPILE.cpp and COMPILE.c into. o files, and then execute LINK.cpp to link. o files and dependent library files into target files.

Example:

TARGET = rtmp_server

OBJ_DIR_THIS = release

C_FLAGS = -Wall -g

CPP_FLAGS =     -I. \
        -I./include \
        -I./include/librtmp \
        -D_GNU_SOURCE \
        -D_LARGEFILE64_SOURCE \
        -D_FILE_OFFSET_BITS=64 \
        -D__STDC_CONSTANT_MACROS 

LD_FLAGS = -lpthread  


COMPILE.cpp = g++ $(C_FLAGS) $(CPP_FLAGS) -c
LINK.cpp = g++
COMPILE.c = gcc $(C_FLAGS) $(CPP_FLAGS) -c
LINK.c = gcc

RELCFLAGS = -O2 -fno-strict-aliasing

SOURCE_PATHS = . liblog librtmp
SOURCES_cpp = $(foreach dir,$(SOURCE_PATHS),$(wildcard $(dir)/*.cpp))
SOURCES_c = $(foreach dir,$(SOURCE_PATHS),$(wildcard $(dir)/*.c))

INCLUDE_PATHS = . include librtmp
HEADERS = $(foreach dir,$(INCLUDE_PATHS),$(wildcard $(dir)/*.h))

RELOBJFILES_cpp = $(SOURCES_cpp:%.cpp=$(OBJ_DIR_THIS)/%.o)
RELOBJFILES_c = $(SOURCES_c:%.c=$(OBJ_DIR_THIS)/%.o)

OBJ_DIR_PATHS = $(foreach dir,$(SOURCE_PATHS), $(OBJ_DIR_THIS)/$(dir))

.PHONY: clean mkdir release

all:    mkdir release

mkdir: 
    mkdir -p $(OBJ_DIR_PATHS)

release:    $(TARGET)

$(TARGET):   $(RELOBJFILES_cpp) $(RELOBJFILES_c)
    $(LINK.cpp) -o $@ $^ -lrt  $(LD_FLAGS)
    @echo === make ok, output: $(TARGET) ===

$(RELOBJFILES_cpp): $(OBJ_DIR_THIS)/%.o: %.cpp $(HEADERS)
    $(COMPILE.cpp) $(RELCFLAGS) -o $@ $<

$(RELOBJFILES_c): $(OBJ_DIR_THIS)/%.o: %.c $(HEADERS)
    $(COMPILE.c) $(RELCFLAGS) -o $@ $<

clean:
    -$(RM) -rf $(TARGET) $(OBJ_DIR_THIS) *.d

Posted by payjo on Tue, 24 Mar 2020 07:50:08 -0700