一、make概述
make是一种代码维护工具make工具会根据makefile文件定义的规则和步骤,完成整个软件项目的代码维护工作。一般用来简化编译工作,可以极大地提高软件开发的效率。 windows下一般由集成开发环境自动生成
linux下需要由我们按照其语法自己编写
Make主要解决两个问题:
1.大量代码的关系维护
大项目中源代码比较多,手工维护、编译时间长而且编译命令复杂,难以记忆及 维护把代码维护命令及编译命令写在makefile文件中,然后再用make工具解析此文 件自动执行相应命令,可实现代码的合理编译
2.减少重复编译时间
在改动其中一个文件的时候,能判断哪些文件被修改过,可以只对该文件进行重 新编译,然后重新链接所有的目标文件,节省编译时间
二、makefile语法
makefile语法规则
目标:依赖文件列表
<Tab> 命令列表
1、目标:
通常是要产生的文件名称,目标可以是可执行文件或其它obj文件,也可是一个 动的名称
2、依赖文件:
是用来输入从而产生目标的文件一个目标通常有几个依赖文件(可以没有)
3、命令:
make执行的动作,一个规则可以含几个命令(可以没有)有多个命令时,每个命 令占一行
举例:
三、make命令
make命令格式:make [ -f file ] [options ] [ targets ]
1. [ -f file ] :
make默认在工作目录中寻找名为GUNmakefile、makefile、Makefile的文件作为makefile输入文件
-f可以指定以上名字以外的文件作为makefile输入文件
2. [ options ]
执行参数:辅助makefile执行
[ options ]的含义:
-v:显示make工具的版本信息
-w:在处理makefile之前和之后显示工作路径
-C dir:读取makefile之前改变工作路径至dir目录
-n:只打印要执行的命令但不执行
-s:执行但不显示执行的命令
3. [ targets ] :
若使用make命令时没有指定目标,则make工具默认会实现makefile文件内的第一个目标,然后退出
指定了make工具要实现的目标,目标可以是一个或多个(多个目标间用空格隔开)。
printf1.c和printf1.h文件在最后一次编译到printf1.o目标文件后没有改动,它们不需重新编译
main可以从源文件中重新编译并链接到没有改变的printf1.o目标文件。
printf1.c和printf1.h源文件有改动,make将在重新编译main之前自动重新编译printf1.o。
四、makefile变量
1.makefile变量类似于C语言中的宏,当makefile被make工具解析时,其中的变量会被展开。
2.变量的作用:
保存文件名列表
保存文件目录列表
保存编译器名
保存编译参数
保存编译的输出
3.makefile的变量分类:
(1)自定义变量
在makefile文件中定义的变量。
make工具传给makefile的变量
(2)系统环境变量
make工具解析makefile前,读取系统环境变量
并设置为makefile的变量。
(3)预定义变量(自动变量)
4.自定义变量语法
(1)定义变量:变量名=变量值
引用变量:$(变量名)或${变量名}
(2)makefile的变量名:makefile变量名可以以数字开头
(3)变量是大小写敏感的
(4)变量一般都在makefile的头部定义
(5)变量一般都在makefile的头部定义
(6)举例:
执行make命令时,make的参数options也可以给makefile设置变量。
makecc=arm-linux-gcc
执行make命令时,make的参数options也可以给makefile设置变量。
makecc=arm-linux-gcc
5.系统环境变量
(1)make工具会拷贝系统的环境变量并将其设置为makefile的变量,在 makefile中 可直接读取或修改拷贝后的变量
(2)举例:
新建makefile2
注释:@,只显示执行结果
终端执行:
export test=10
make clean –f makefile2
结果如下:
6. 预定义变量
makefile中有许多预定义变量,这些变量具有特殊的含义,可在makefile中直 接使用。
$@ 目标名
$* 目标名中除含扩展名的部分:扩展名包括:S、s、C、c、cc、cp、cpp、o、a等
$< 依赖文件列表中的第一个文件
$^ 依赖文件列表中除去重复文件的部分
$+ 依赖文件列表中所有的文件
$? 依赖文件列表中比目标文件新的文件
AR 归档维护程序的程序名,默认值为ar
ARFLAGS 归档维护程序的选项
AS 汇编程序的名称,默认值为as
ASFLAGS 汇编程序的选项
CC C编译器的名称,默认值为cc
CFLAGS C编译器的选项
CPP C预编译器的名称,默认值为$(CC) -E
CPPFLAGS C预编译的选项
CXX C++编译器的名称,默认值为g++
CXXFLAGS C++编译器的选项
---------------------------------------------------------------------------------------
附带三种变量的栗子:
编写Makefile完成计算器程序的编译,并通过假想目标(clean)清除目标文件
第一步:不使用任何变量完成功能
main:main.o add.o div.o mux.o sub.o
gcc main.o add.o div.omux.o sub.o -o main
main.o:main.c add.h div.h mux.h sub.h
gcc -c main.c -o main.o
add.o:add.c add.h
gcc -c add.c -o add.o
div.o:div.c div.h
gcc -c div.c -o div.o
mux.o:mux.c mux.h
gcc -c mux.c -o mux.o
sub.o:sub.c sub.h
gcc -c sub.c -o sub.o
clean:
rm *.o
第二步:使用自定义变量让程序更加通用
file=gcc
#file=gcc
obj:=main.o add.o div.o mux.o sub.o
target=main
cflags=-Wall -g
$(target):$(obj)
$(file) $(obj) -o$(target) $(cflags)
main.o:main.c add.h div.h mux.h sub.h
$(file) -c main.c -omain.o $(cflags)
add.o:add.c add.h
$(file) -c add.c -oadd.o $(cflags)
div.o:div.c div.h
$(file) -c div.c -odiv.o $(cflags)
mux.o:mux.c mux.h
$(file) -c mux.c -omux.o $(cflags)
sub.o:sub.c sub.h
$(file) -c sub.c -osub.o $(cflags)
clean:
rm $(obj) $(target)
第三步:使用预定义变量让程序更加通用
obj:=main.o add.o div.o mux.o sub.o
target=main
CFLAGS=-Wall -g
$(target):$(obj)
$(file) $^ -o $@$(CFLAGS)
main.o:main.c add.h div.h mux.h sub.h
$(file) -c $@ $(CFLAGS)
add.o:add.c add.h
$(file) -c $@ $(CFLAGS)
div.o:div.c div.h
$(file) -c $@ $(CFLAGS)
mux.o:mux.c mux.h
$(file) -c $@ $(CFLAGS)
sub.o:sub.c sub.h
$(file) -c $@ $(CFLAGS)
clean:
rm $(obj) $(target)
————————————————
版权声明:本文为CSDN博主「Amarao」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jinmie0193/article/details/79842137