make工程文件编写

make工程管理器时一个自动编译管理器,命令格式如下:

make [选项] [make工程文件]

常用选项:
-d 显示调试信息
-f 文件 指定make 文件
-n 不执行makefile中的命令,只显示输出这些命令
-s 执行但不显示任何信息
一个Makefile文件主要含有一系列make规则,每条规则包含以下内容:

目标文件列表:依赖文件列表
< TAB >命令列表

Makefile中的变量与shell中变量的定义和使用基本一致,make还可以使用环境变量、自动变量和预定义变量

makefile中常见预定义变量

命令格式含义
AR库文件维护程序的名称,默认值为ar
AS汇编程序的名称,默认值为as
CCc编译器名称,默认值为cc
CPPc预编译器名称,默认值为$(CC)-E
CXXc++编译器名称,默认值为g++
FCFORTRAN编译器名称,默认值为f77
RM文件删除程序名称,默认值为rm -f
ARFLAGS库文件维护程序的选项,无默认值
ASFLAGS汇编程序的选项,无默认值
CFLAGSC编译器选项,无默认值
CPPFLAGSc预编译器的选项,无默认值
CXXFLAGSc++编译器的选项,无默认值
FFLAGSFRTRAN编译器选项,无默认值

makefile中常见自动变量

命令格式含义
$*不包含扩展名的目标文件名称
$+包含所有依赖文件,以空格分开,以出现先后为顺序,可能重复
$<第一个依赖文件的名称
$?所有时间戳比目标文件晚的依赖文件,以空格分开
$@目标文件的完整名称
$^所有不重复的依赖文件,以空格分开
$%如果目标是归档成员,该变量表示目标归档成员名称

makefile文件主要包含五部分内容:显示规则、隐式规则、变量定义、文件指示和注释

### 如何编写 MakeMakefile 文件 #### 定义目标和依赖关系 Makefile 中的目标是指最终想要生成的文件,通常是可执行文件或库文件。依赖项则是指生成该目标所需的其他文件。每条规则由三部分组成:目标、依赖项列表以及构建此目标所需的一系列命令。 对于一个简单的 C++ 项目来说,假设存在 `main.cpp` 和两个头文件 `mylib.h` 及其实现文件 `mylib.cpp`,那么可以在 Makefile 中这样定义: ```makefile # 目标: mybin (可执行文件名) mybin: main.o mylib.o $(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS) # 依赖关系及编译指令 %.o: %.cpp $(CXX) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< ``` 这里使用了模式规则 `%` 来表示任意源文件与其对应的对象文件之间的转换[^1]。 #### 设置变量简化维护工作 为了使 Makefile 更加灵活易读,在其中设置一些常用的预处理器宏是非常有必要的。比如指定 C++ 编译器 (`CXX`) 或者传递给编译器的一些标志位(`CPPFLAGS`, `CFLAGS`)等: ```makefile CC=gcc CXX=g++ AR=ar RM=rm -f SRCDIR=./src OBJDIR=./obj BINDIR=./bin INCS=-I. LIBS= CPPFLAGS=$(INCS) CFLAGS=-Wall -g LDFLAGS= LDLIBS=$(LIBS) OBJS=$(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(wildcard $(SRCDIR)/*.cpp)) .PHONY: all clean all: directories $(BINDIR)/mybin directories: mkdir -p $(OBJDIR) $(BINDIR) $(OBJDIR)/%.o : $(SRCDIR)/%.cpp | directories $(CXX) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< $(BINDIR)/% : $(OBJDIR)/%.o $(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS) clean: $(RM) $(OBJDIR)/*.o $(BINDIR)/* rmdir $(OBJDIR) $(BINDIR) ``` 这段代码不仅设置了多个路径相关的环境变量以便于管理和扩展大型工程;还利用了 `.PHONY` 关键字声明了一些伪目标(即不会对应任何实际存在的文件),如 `all` 和 `clean`,使得用户可以通过运行 `make all` 或者 `make clean` 方便地完成整个项目的编译或是清理操作[^2]。 #### 自动生成依赖关系 当项目变得越来越大时手动维护各个源码间的相互依赖将会非常麻烦。幸运的是 GNU Make 提供了一种方法来自动生成这种信息并将其嵌入到 Makefile 当中去。只需要稍微修改下上面的例子就可以做到这一点: ```makefile DEPFILES := $(OBJS:.o=.d) -include $(DEPFILES) $(OBJDIR)/%.o : $(SRCDIR)/%.cpp | directories $(CXX) $(CPPFLAGS) $(CFLAGS) -MMD -MP -MF $(@:%.o=%.d) -c -o $@ $< ``` 上述改动引入了一个新的变量 DEPFILES ,它包含了所有 .d 文件的名字——这些就是用来记录各 cpp 文件之间依赖性的临时文件。接着 `-include` 指令告诉 make 尝试加载那些可能不存在的 d 文件作为额外输入。最后一步是在每次编译之前更新相应的 d 文件内容,这通过向 cxx 命令行添加特定选项来实现[-MMD, -MP][^3].
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值