工程管理器 make (来自GNU计划)
在运用Make工程管理器时我们会发现最重要的部分就是编写Makefile,在提到make时候我们更多也更加习惯地提到Makefile。我们在做一个工程时会编写很多的源文件,如果用gcc编译的话编译速率太慢效率太低,这时候全自动的Make工程管理器就能带来很大的便利。
Make为什么被称为全自动化的编译器?
1)、按规则编译使用方便:通过命令”make”即可启动编译,Make工程管理器就根据规则文件Makefile来编译
2)、按时间戳编译调试效率高:Make会自动检查每个源文件的时间戳的时间,如果发现时间更新就编译该文件,如果时间戳没变就不再编译该文件
Makefile
组成部分:
目标文件:依赖文件
<Tab>编译规则命令行
编写程序模拟一个实现加减乘除功能的计算器并用Make工程管理器实现多个源文件的调试
功能块源文件组成:add.csub.c mul.c div.c main.c
功能目录组成:add submul div test scripts Makefile
tree型目录
|-- Makefile
|-- add
| |-- Makefile
| `-- src
| |-- add.c
| `-- add.o
|-- cal
|-- div
| |-- Makefile
| `-- src
| |-- div.c
| `-- div.o
|-- mul
| |-- Makefile
| `-- src
| |-- mul.c
| `-- mul.o
|-- scripts
| `--Makefile
|-- sub
| |-- Makefile
| `-- src
| |-- sub.c
| `-- sub.o
`-- test
|-- Makefile
`-- src
|-- main.c
`-- main.o
scripts /Makefile(在脚本功能目录下的Makefile主要进行一些变量赋值,在编写时编者需要了解基本的赋值语句,在这里以#开头均为注解)
CC := gcc
CFLAGS := -Wall -O3
Libs = -lpthread
Target := cal #目标文件名
Source := $(wildcard src/*.c) #将所有src 目录下.c文件存放到Source变量中去
Objs := $(patsubst %.c,%.o,$(Source)) #将Source中.c文件编译成.o文件并存放到Objs变量中
Modules += add sub mul div test #将所有的功能目录存放到Modules变量中
AllObjs := $(addsuffix /src/*.o,$(Modules)) #依次将Modules中存放的目录下的src目录下的.o文件存放到AllObjs中
总控Makefile (在总控Makefile中主要执行进入各个子目录中读取Makefile并进行make编译的嵌套功能)
include scripts/Makefile
modules_make = $(MAKE) -C $(1); #嵌套执行,读取子目录的Makefile并执行make命令
modules_clean = $(MAKE) clean -C $(1); #进入子目录并进行clean操作
.PHONY: all mm mc clean
all: $(Target)
mm:
@$(foreach n,$(Modules),$(call modules_make,$(n))) #先将Modules中存放的目录循环依次传送到变量n中,然后再将n中内容依次复制给参数modules_make中的变量$(1),$(2)
mc:
@$(foreach n,$(Modules),$(call modules_clean,$(n))) #先将Modules中存放的目录循环依次传送到变量n中,然后再将n中内容依次复制给参数modules_clean中的变量$(1),$(2)
$(Target) : mm
$(CC)$(CFLAGS) -o $(Target) $(AllObjs) $(Libs) # 编译成可执行文件gcc –Wall–o3 –o cal add.o sub.o mul.o div.o main.o -lpthread
@echo $(Target) make done! #打印 cal make done!
clean : mc
rm-rf $(Target) #清除目标文件中的.o文件
@echo clean done! #打印 clean done!
功能块Makefile (在各个独立的子功能块编写Makefile文件)
include ../scripts/Makefile
all:$(Objs) #gcc –c ./src /.c文件 –o .o文件
clean:
rm-rf $(Objs) #删除各目录下目录src中的.o文件