Makefile 编译多级目录多个目标文件模板
对于当前目录结构下的Makefile(基于银行系统Bank)
目录树
. tree
├── Makefile
├── bin
│ ├── client
│ └── server
├── build
│ ├── clientcore.o
│ ├── clientimpl.o
│ ├── clientmain.o
│ ├── clientview.o
│ ├── servercore.o
│ ├── serverimpl.o
│ ├── servermain.o
│ └── tools.o
├── data
├── include
│ ├── bankaccount.h
│ ├── clientcore.h
│ ├── clientimpl.h
│ ├── clientview.h
│ ├── servercore.h
│ ├── serverimpl.h
│ └── tools.h
├── lib
├── run.sh
└── src
├── client
│ ├── Makefile
│ ├── clientcore.c
│ ├── clientimpl.c
│ ├── clientmain.c
│ └── clientview.c
├── server
│ ├── Makefile
│ ├── servercore.c
│ ├── serverimpl.c
│ └── servermain.c
└── tools
├── Makefile
└── tools.c
9 directories, 30 files
根目录Makefile模板
CC = gcc
# 添加的编译选项
CFLAGS = -Wall -Werror
# 需要链接的库
CLIBS =
# 根目录路径
TOP_DIR = $(PWD)
# TOP_DIR = .
# 存放中间文件的路径
BUILD_DIR = $(TOP_DIR)/build
# 存放库文件的中间路径
LIB_DIR = $(TOP_DIR)/lib
# 存放可执行文件的路就路径
BIN_DIR = $(TOP_DIR)/bin
# 存放头文件的文件夹
INC_DIR = $(TOP_DIR)/include
# 存放.c 源文件的路径
SRC_DIR := \
$(TOP_DIR)/src/client \
$(TOP_DIR)/src/server \
$(TOP_DIR)/src/tools
SRC_SERVER_DIR := $(TOP_DIR)/src/server
SRC_CLIENT_DIR := $(TOP_DIR)/src/client
SRC_TOOLS_DIR := $(TOP_DIR)/src/tools
# 在头文件路径前面加上-I
INCLUDE = $(patsubst %, -I %, $(INC_DIR))
# 在库文件路径前面加上-L
LIB = $(patsubst %, -L%, %(LIB_DIR))
VPATH = $(SRC_DIR)
# 将变量添加进环境变量表中,进入子目录的makefile时可以共享
export INCLUDE INC_DIR BIN_DIR BUILD_DIR TOP_DIR CC CFLAGS CLIBS LIB_DIR LIB \
SRC_SERVER_DIR \
SRC_CLIENT_DIR \
SRC_TOOLS_DIR
# 去到各个目录执行makefile
all:CHECKDIR $(VPATH)
CHECKDIR:
@mkdir -p $(BUILD_DIR) $(BIN_DIR) $(LIB_DIR)
$(VPATH): RUN
@make -C $@
RUN:
# 清理所有编译产生的文件
.PHONY:clean
clean:
rm -rf $(BUILD_DIR) $(BIN_DIR) $(LIB_DIR)
需要编译出可执行文件目录的Makefile模板(以server目录下的makefile文件示例)
# 路径
DIR = $(SRC_SERVER_DIR)
# 需要链接的库
LIBS := $(LIBS) -lpthread -ltools
# 得到带路径的.c 文件
FILES := $(foreach dir,$(DIR),$(wildcard $(dir)/*.c))
# 得到不带路径的.c 文件
FILENDIR := $(notdir $(FILES))
# 将工程中的.c 文件替换成 ./build 目录下对应的目标文件 .o
OBJS = $(patsubst %,$(BUILD_DIR)/%,$(patsubst %c,%o, $(FILENDIR)))
# 可执行文件名
TARGET = $(patsubst %main.c,%,$(notdir $(foreach dir, $(DIR), $(wildcard $(dir)/*main.c))))
# 可执行文件列表
# TARGETLIST = $(patsubst %main.c, %sys, $(TARGET))
# 运行
$(BIN_DIR)/$(TARGET): $(OBJS)
$(CC) $(FLAGS) -o $@ $^ $(LIB) $(LIBS)
$(OBJS): $(BUILD_DIR)/%.o: %.c
$(CC) $(FLAGS) $(INCLUDE) $(LIB) -c -o $@ $^
需要编译出库文件目录的Makefile模板(以tools目录下的makefile文件示例)
# 路径
DIR = $(SRC_TOOLS_DIR)
# 编译选项 记得加上 -fpic -shared
FLAG += -fpic -shared
# 得到带路径的.c 文件
FILES := $(foreach dir,$(DIR),$(wildcard $(dir)/*.c))
# 得到不带路径的.c 文件
FILENDIR := $(notdir $(FILES))
# 将工程中的.c 文件替换成 ./build 目录下对应的目标文件 .o
OBJS = $(patsubst %,$(BUILD_DIR)/%,$(patsubst %c,%o, $(FILENDIR)))
# 可执行文件名 注意必须以lib开头.so结尾
TARGET = $(patsubst %.c,lib%.so,$(notdir $(foreach dir, $(DIR), $(wildcard $(dir)/*.c))))
# 运行
$(LIB_DIR)/$(TARGET): $(OBJS)
$(CC) $(FLAG) -o $@ $^
$(OBJS): $(BUILD_DIR)/%.o: %.c
$(CC) $(FLAG) $(INCLUDE) -c -o $@ $^
调试语句
$(shell echo $(需要输出的变量) > a.txt)
附:Makefile语法基础 or 陈皓老师的《跟我一起写Makefile》也是经典
End...放一个上面的银行系统源码(github太难进了,只好放在gitee上了)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)