本篇文章提供了一个c++项目的makefile模板。本人也在慢慢摸索中,代码肯定还有很多不专业和错误之处,欢迎大家优化和指正。
CXX = g++
SRC_BASE = $(wildcard ./include/base/*.cpp)
SRC_DATA = $(wildcard ./include/data/*.cpp)
OBJ_BASE = $(patsubst %.cpp, %.o, $(SRC_BASE))
OBJ_DATA = $(patsubst %.cpp, %.o, $(SRC_DATA))
SRC = $(SRC_BASE) $(SRC_DATA)
OBJ = $(patsubst %.cpp, %.o, $(SRC))
ROOT=$(shell pwd)
DIR=-I$(ROOT)
CFLAGS = -ldl -lpthread -lglog
LIB_MYLIB = $(ROOT)/libmylib.so
init: $(OBJ)
all: $(OBJ) main.x
main: main.x
main.x: ./machines/main.o
$(CXX) -o main.x ./machines/main.o $(OBJ) $(LIB_MYLIB) $(CFLAGS)
-include tools/*.d ./include/*/*.d
%.o: %.cpp
$(CXX) -o $@ $< $(CFLAGS) $(DIR) -MMD -MP -c
%.x: ./machines/%.o
$(CXX) -o $@ $< $(BASEOBJ) $(LIB) $(CFLAGS)
main.o: ./machines/main.cpp
$(CXX) -c ./machines/main.cpp $(DIR)
test:
@echo $(SRC)
@echo "--------------"
@echo $(OBJ)
.PHONY: clean
clean:
rm -f */*/*.o */*.o *.x ./machines/*.x */*/*.d */*.d *.o
解析
SRC_*
:取某个文件夹下所有的源代码的名字OBJ_*
:使用带有正则表达式的字符串替换,将.cpp
替换为.o
SRC
、OBJ
代表所有源代码名字的汇总(不包含main文件),一个是.cpp
,一个是.o
ROOT
:表示根目录,使用shell命令获取当前目录路径。DIR
:指定头文件的搜索路径为项目根目录。源代码中头文件包含的路径也应该以根目录为主。- main文件存放在
machines
文件夹下,编译出的可执行文件(main.x
)放在了根目录下。如果有多个main文件,可以统一放在main:
后面一起编译. .d
文件的作用:在make时会出现一种情况:如果我没有修改cpp文件,只是修改了它include的一个.h,此时如果执行make它是不会重新编译的,会提示”已经是最新的“。加了.d之后,即使只改了.h文件,他也会重新编译。- test 提供了一个在makefile里执行一系列的shell命令模板。
%.o: %.cpp
编译所有的cpp文件(不包含main),生成对应的.o和.d文件
文件组织架构
-- root
-- include
-- base
-- many .cpp
-- data
-- many .cpp
-- machines
-- main.cpp
-- Makefile
-- libmylib.so