本章中带大家了解Makefile,MakefileC工程很好的一个管理工具
文章目录
1.Makefile提要
(1)Makefile是由make读入的唯一配置文件,一般包括:
- make工具创建的目标体(target),通常是目标文件或可执行文件
- 要创建的目标体所依赖的文件(dependency_file)
- 创建每个目标体时所需要运行的命令(command)
注意:命令行前面必须是一个“TAB键”,否则编译错误为:***missing separator. Stop。
(2)快捷命令:
可以直接运行make
命令
选项:
-C dir读入指定目录下的Makefile
-f file读入当前目录下的file文件作为Makefile(比如你的Makefile重命名为myMakefile 则应该make -f myMakefile)
-i 忽略所有的命令执行错误
-I dir指定被包含的Makefile所在目录
-n 只打印要执行的命令,但是不执行这些命令
-p 显示make变量数据库和隐含规则
-s 在执行命令时不显示命令
-w 如果make在执行过程中改变目录,打印当前目录名
(3)潜在规则
- 隐含规则1:编译C程序的隐含规则
2. Makefile初探
2.1创建工程文件并添加内容
touch main.c tool1.c tool1.h tool2.c tool2.h
# 创建五个空白文件
vim * -p
# 以此打开这五个文件
五个文件内容分别如下所示:
"tool1.h"
#ifndef TOOL1_H__
#define TOOL1_H__
# 声明函数
void mytoo1(void);
#endif
"tool1.c"
#include <stdio.h>
#incldue "tool1.h"
# 定义函数
void mytool1(void)
{
printf("tool1 print\n");
}
"tool2.h"
#ifndef TOOL2_H__
#define TOOL2_H__
# 声明函数
void mytoo2(void);
#endif
"tool1.c"
#include <stdio.h>
#incldue "tool2.h"
# 定义函数
void mytool2(void)
{
printf("tool2 print\n");
}
//main.c
#include <stdio.h>
#include "tool1.h"
#include "tool2.h"
int main(){
mytool1();
mytool2();
return 0;
}
2.2通过gcc编译运行
gcc *.c && ls
./a.out
rm a.out
2.3创建Makefile文件
vim Makefile
# 自定义依赖关系,源文件(后缀为.c)经过编译汇编生成目标文件(后缀为.o)
# 目标文件执行生成可执行文件(类似与mytool)
mytools:main.o tool1.o tool2.o
# 写gcc命令时候,前面要tab按键一下
# 不写-o参数,生成默认的可执行文件名为a.out,这里我们修改为mytool
gcc main.o tool1.o tool2.o -o mytools
main.o:main.c
#-Wall 可以看到所有的警告
#-g 可以调试
#-c 只允许执行到汇编步骤,不允许链接。
gcc main.c -c -Wall -g -o main.o
tool1.o:tool1.c
gcc tool1.c -c -Wall -g -o tool1.o
tool2.o:tool2.c
gcc tool2.c -c -Wall -g -o tool2.o
clean:
# rm 删除指令,删除所有后缀为.o文件,删除mytool这个可执行文件
# -rf 强制删除并且递归删除,否则的话会一直询问我们是否需要删除
rm *.o mytools -rf
直接执行make
和make clean
3. 优化Makefile
3.1 变量替换
# OBJS 代替 依赖文件
# CC 代替 gcc
# CFLAGS 代替 编译命令
OBJS=main.o tool1.o tool2.o
CC=gcc
CFLAGS=-c -Wall -g
mytool:$(OBJS)
$(CC) $(OBJS) -o mytool
main.o:main.c
$(CC) main.c $(CFLAGS) -o main.o
tool1.o:tool1.c
$(CC) tool1.c $(CFLAGS) -o tool1.o
tool2.o:tool2.c
$(CC) tool2.c $(CFLAGS) -o tool2.o
clean:
rm *.o mytool -rf
上述代码中,用OBJS
替换了依赖文件,用CC
替换了gcc编译器,用CFLAGS
替换了编译参数。
3.2 常量替换
# $^ 代替 上面的指令
# RM 代替 rm -f
# $@ 代替 目标文件
OBJS=main.o tool1.o tool2.o
CC=gcc
CFLAGS=-c -Wall -g
mytool:$(OBJS)
$(CC) $^ -o mytool
main.o:main.c
$(CC) $^ $(CFLAGS) -o $@
tool1.o:tool1.c
$(CC) $^ $(CFLAGS) -o $@
tool2.o:tool2.c
$(CC) $^ $(CFLAGS) -o $@
clean:
$(RM) *.o mytool -r
上述代码中,用$^
替代上面的指令,用RM
替代rm -f
用$@
替代了目标文件*.o
3.3提炼Makefile模板
# 6-11行代码相似性很强,可以提取出一个公式模版
# %.o:%.c
# $(CC) $^ $(CFLAGS) -o $@
# 百分号相当于一个通配符
OBJS=main.o tool1.o tool2.o
CC=gcc
CFLAGS=-c -Wall -g
mytool:$(OBJS)
$(CC) $^ -o mytool
%.o:%.c
$(CC) $^ $(CFLAGS) -o $@
clean:
$(RM) *.o mytool -r