当前位置: 首页 > news >正文

《C++——makefile》

一、Makefile 是什么

Makefile 是一个包含了一系列规则的文件,这些规则告诉 make 工具如何编译和链接程序。make 工具会根据 Makefile 中的规则,判断哪些文件需要重新编译,然后执行相应的命令,最终生成可执行文件或库。

二、基本规则格式

Makefile 的基本规则格式如下:

目标: 依赖命令
  • 目标:可以是可执行文件、目标文件,也可以是一个动作如 clean,可以理解为最后要生成的是什么。
  • 依赖:生成目标所需要的文件或其他目标。
  • 命令:生成目标所需要执行的命令(需要以 Tab 键开头)。

例如,我们有一个简单的 hello.cpp 文件,要编译它生成可执行文件 hello,可以写这样的规则:

hello: hello.cppg++ hello.cpp -o hello

在这里插入图片描述

三、变量的使用

在 Makefile 中,我们可以使用变量来简化书写,尤其是当编译选项、文件列表等需要重复使用时。

我们可以自定义变量来表示编译选项、源文件列表等。例如:

# 定义编译器
CXX = g++
# 定义编译选项
CXXFLAGS = -std=c++11 -Wall
# 定义源文件列表
SRCS = hello.cpp world.cpp
# 定义目标文件列表,将源文件的 .cpp 替换为 .o
OBJS = $(SRCS:.cpp=.o)
# 定义可执行文件名
TARGET = my_program

可以理解为给这个文件定义了一个集合别名,就像模板一样

然后在规则中使用这些变量:

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

这里 $^ 表示所有的依赖文件,$< 表示第一个依赖文件,$@ 表示目标文件。

如果不用自定义:

# 最终可执行文件
my_program: hello.o world.og++ -std=c++11 -Wall hello.o world.o -o my_program# 编译hello.o
hello.o: hello.cppg++ -std=c++11 -Wall -c hello.cpp -o hello.o# 编译world.o
world.o: world.cppg++ -std=c++11 -Wall -c world.cpp -o world.o

怎么比自定义还短?那我用自定义不是多此一举吗?
虽然在极简单的小项目中,直接写命令可能看起来更短,但当项目规模扩大、需求变化时,自定义变量的优势会非常明显,就如c++中的#define,typedef一样,在上千上万行代码里,一个一个去更改变量,不如提前定义好只需要修改定义的部分就行

四、多目标与伪目标

如果我们有多个可执行文件需要编译,可以在 Makefile 中定义多个目标。例如,我们有 server、client 两个可执行文件:

CXX = g++
CXXFLAGS = -std=c++11 -Wall
LDFLAGS = -lpthreadSERVER_SRCS = server.cpp
CLIENT_SRCS = client.cppSERVER_OBJS = $(SERVER_SRCS:.cpp=.o)
CLIENT_OBJS = $(CLIENT_SRCS:.cpp=.o)all: server clientserver: $(SERVER_OBJS)$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
client: $(CLIENT_OBJS)$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)%.o: %.cpp$(CXX) $(CXXFLAGS) -c $< -o $@.PHONY: clean
clean:rm -f server client $(SERVER_OBJS) $(CLIENT_OBJS)

在这里插入图片描述

这里使用了伪目标.PHONY: clean
伪目标不是一个实际的文件,而是一个动作的标识。最常见的伪目标是 clean,用于清理编译生成的文件。我们需要用 .PHONY 来声明伪目标,防止项目中存在同名文件时 make 误判。例如上面的 clean 目标,执行 make clean 会删除生成的可执行文件和目标文件。

五、实战

CFLAG= -std=c++11 -I ../../build/release-install-cpp11/include/
LFLAG= -L../../build/release-install-cpp11/lib  -lmuduo_net -lmuduo_base -pthread
all: server client text
server: server.cppg++  $(CFLAG) $^ -o $@ $(LFLAG)
client: client.cppg++  $(CFLAG) $^ -o $@ $(LFLAG)
text: text.cppg++  $(CFLAG) $^ -o $@ $(LFLAG).PHONY:clean
clean:rm -f server client
  1. 变量定义:
    CFLAG:编译选项,指定 C++11 标准和第三方库(如 muduo)的头文件路径。
    LFLAG:链接选项,指定库文件路径及需要链接的库(muduo 网络库、基础库和线程库)。
  2. 目标规则:
    默认目标 all 会依次编译 server、client、text 三个可执行文件。
    每个目标对应一个 .cpp 源文件,通过统一的 g++ 命令编译,利用 $^(依赖文件)和 $@(目标文件)简化书写。
  3. 清理操作:
    clean 伪目标用于删除编译生成的可执行文件,但当前缺少对 text 的清理,需补充以避免残留。

通用 Makefile 模板:

# 编译器与选项
CXX = g++
CXXFLAGS = -std=c++11 -Wall -g
LDFLAGS = # 链接库(如需要可添加-lpthread -lm等)# 项目文件
TARGET = main
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)# 默认编译
all: $(TARGET)# 链接
$(TARGET): $(OBJS)$(CXX) $^ -o $@ $(LDFLAGS)# 编译
%.o: %.cpp$(CXX) $(CXXFLAGS) -c $< -o $@# 清理
clean:rm -f $(OBJS) $(TARGET)# 伪目标
.PHONY: all clean

一般只需要:

  • 改文件名:修改TARGET的值
  • 加库:在LDFLAGS后添加(如-L/path -lmuduo)
  • 改标准:调整CXXFLAGS中的-std=c++11(如c++17)

如果需要分开执行文件,可以不需要编译,生成多个执行文件

http://www.dtcms.com/a/358210.html

相关文章:

  • 日志ELK、ELFK、EFK
  • 使用Python和GitHub构建京东数据自动化采集项目
  • 线程相关问题(AI回答)
  • 营业执照经营范围行业提取工具库项目方案解读(php封装库)
  • 【学Python自动化】 4. Python 控制流与函数学习笔记
  • FlowUs AI-FlowUs息流推出的AI创作助手
  • DAY 18 推断聚类后簇的类型 - 2025.8.30
  • ADB常用命令大全
  • Linux驱动开发重要操作汇总
  • 1.8 Memory
  • vue表格底部添加合计栏,且能跟主表同时滑动
  • 【Linux基础】深入理解计算机启动原理:MBR主引导记录详解
  • U-Boot移植过程中的关键目录文件解析
  • 循迹小车控制实验:实验介绍
  • 基于FPGA的简易医疗呼叫器实现,包含testbench
  • Linux 830 shell:expect,ss -ant ,while IFS=read -r line,
  • 在 VS2017 中使用 Visual Leak Detector 检测内存泄漏(记录一下 以前开发中使用过)
  • 数据结构(C语言篇):(七)双向链表
  • 学习游戏制作记录(视觉上的优化)
  • GRPO(组相对策略优化):大模型强化学习的高效进化
  • MySQL独占间隙锁为什么会互相兼容?
  • 基于Ultralytics YOLO通用目标检测训练体系与PyTorch EfficientNet的图像分类体系实现
  • 用Git在 Ubuntu 22.04(Git 2.34.1)把 ROS 2 工作空间上传到全新的 GitHub 仓库 步骤
  • MCU启动过程简介
  • 为多种业态注入智能化发展新活力的智慧地产开源了
  • Java 常见异常系列:ClassNotFoundException 类找不到
  • Qt线程提升:深度指南与最佳实践
  • 操作系统上的Docker安装指南:解锁容器化新世界
  • 《潮汐调和分析原理和应用》之四S_Tide使用1
  • 一个wordpress的网站需要什么样的服务器配置