第5章 linux工程管理器makefile
创始人
2024-06-03 00:50:57
0

1.1 make工程管理器简介

可以试想一下,有一个上百个文件的代码构成的项目,如果其中只有一个或少数几个文件进行了修改,如果再从头到尾将每一个文件都重新编译是个比较繁琐的过程。

为此,引入了 Make 工程管理器的概念,工程管理器指管理较多的文件,它是自动管理器能根据文件时间自动发现更新过的文件而减少编译的工作量,同时通过读入Makefile 文件来执行大量的编译工作。

1.2 makefile 规则格式

target: dependency_files //目标项:依赖项

< TAB >command //必须以 tab 开头, command 编译命令

注意点:在写command 命令行的时候,必须要在前面按 TAB 键。

例如,有Makefile 文件,内容如下:

使用make 编译:

对于该Makefile 文件,程序 make 处理过程如下:

·make 程序首先读到第 1 行的目标文件 main.exe 和它的两个依赖文件 main.o 和 func.o;然后比较文件main.exe 和 main.o/func.o 的产生时间,如果 main.exe 比 main.o/func.o 旧的话,则执行第 2 条命令,以产生目标文件 main.exe。

·在执行第2 行的命令前,它首先会查看 makefile 中的其他定义,看有没有以第 1 行 main.o 和 func.o 为目标文件的依赖文件,如果有的话,继续按照(1)、 (2)的方式匹配下去。

·根据(2)的匹配过程, make 程序发现第 3 行有目标文件 main.o 依赖于 main.cpp,则比较目 main.o 与它的依赖文件 main.cpp 的文件新旧,如果 main.o 比 main.cpp 旧,则执行第 4 行的命令以产生目标文件 main.o。

·在执行第4 条命令时,main.cpp 在文件 makefile 不再有依赖文件的定义,make 程序不再继续往下匹配,而是执行第 4 条命令,产生目标文件 main.o

·目标文件func.o 按照上面的同样方式判断产生。

·执行(3)、 (4)产生完 main.o 和 func.o 以后,则第 2 行的命令可以顺利地执行了,最终产生了第 1 行的目标文件 main.exe。

归结:

1)目标文件不存在,执行命令

2)文件已经更新了,执行命令

1.3 Makefile 中特殊处理与伪目标

.PHONY 是makefile 文件的关键字,表示它后面列表中的目标均为伪目标。

.PHONY:b
b:echo ‘b’ #通常用@echo “hello”

伪目标通常用在清理文件、强制重新编译等情况下。一般伪目标没有时间的检查,一旦指明了就会执行。

示例1:main.c 函数,func.c 函数为前面计算+,-,*,/运算的程序。

#vim Makefile #系统默认的文件名为 Makefile

在VIM编辑器Makefile文件内容如下:

#表示要想生成 main.exe 文件,要依赖于 main.o 和 func.o 文件
#如果 main.o,func.o 已经存在了,就链接成 main.exe
main.exe:main.o func.o gcc -o main.exe main.o func.o
#表示 main.o 文件依赖于 main.c 文件
#编译 main.c,默认生成 main.o。可写为: gcc –c main.c –o main.o
main.o:main.c  gcc -c main.c 
#表示 func.o 文件依赖于 func.c 文件
#如果 func.c 存在,则编译 func.c ,生成 func.o
func.o:func.c gcc -c func.c 
#表示后面的是伪目标, 通常用在清理文件、强制重新编译等情况下
#先执行clean字段,再执行main.exe字段
.PHONY:rebuild clean 
rebuild:clean main.exe
#最后删除.o 和.exe 的文件
clean:rm -rf main.o func.o main.exe 

1)按ESC 键之后, :wq 保存退出(vim退出方式)。

注意:和shell 编程相同,在 Makefile 中,也用“ #”号表示注释。

2)再执行下面的命令:

#make //直接 make,即从默认文件名( Makefile)的第一行开始执行

#make clean //表示执行 clean: 开始的命令段

#make func.o //表示执行 func.o: 开始的命令段

#make rebuild //则先执行清除,再重新编译连接

如果不用系统默认的文件名Makefile,而是用户随便起的一个名字。

如:

#vi Makefile11

则make 后面必须要加上 -f Makefile11。

如:

#make –f Makefile11 clean //表示执行 clean: 开始的命令段

#make –f Makefile11 main.exe //表示执行 main.exe: 开始的命令段

1.4 变量、规则与内置函数

1)变量

随着软件项目的变大、变复杂,源文件也越来越多,如果采用前面的方式写makefile 文件,将会使 makefile也变得复杂而难于维护。

通过make 支持的变量定义、规则和内置函数,可以写出通用性较强的 makefile 文件,使得同一个 makefile 文件能够适应不能的项目。

变量:用来代替一个文本字符串

定义变量的2 种方法:

变量名=变量值递规变量展开(几个变量共享一个值) //不常用

变量名:=变量值简单变量展开(类似于 C++的赋值) //通常采用这种形式

使用变量的一般方法:

$(变量名)=??? //赋值

???=$(变量名) //引用

例:将以前的那个可以写为:

OBJS:=main.o func.o            //相当于 main.o func.o
EXE:=main.exe
$(EXE):$(OBJS)g++ -o $(EXE) $(OBJS)
main.o:main.cppg++ -c main.cpp –o main.o
func.o:func.cppg++ -c func.cpp –o func.o
clean:rm –rf $(EXE) $(OBJS) 

变量分为:用户自定义变量,自动变量,预定义变量,环境变量。

上面的例子就是用户自定义变量。

(1)自动变量

指在使用的时候,自动用特定的值替换。

常用的如表2.1:

变量

说明

$@

当前规则的目标文件

$<

当前规则的第一个依赖文件

$^

当前规则的所有依赖文件,以逗号分隔

$?

规则中日期新于目标文件的所有相关文件列表,逗号分隔

$(@D)

目标文件的目录名部分

$(@F)

目标文件的文件名部分

示例1:用自动变量。

OBJS:= main.o func.o //$(OBJS)相当于 main.o func.o (原样替换)

EXE:= main.exe

CFLAGS:= -Wall -O2 -fpic #显示所有警告信息,优化级别为 2

LIBFUNCSO:= libfunc.so #动态库

LIBFUNCA:= libfunc.a #静态库

$(EXE):$(OBJS) $(LIBFUNCSO) $(LIBFUNCA)

gcc -o $@ $< -L./ -lfunc

main.o: main.c

gcc -c $(CFLAGS) $< -o $@

func.o: func.c

gcc -c $(CFLAGS) $< -o $@

libfunc.a: func.o

ar rcsv $@ $<

libfunc.so: func.o

gcc -shared -o $@ $<

cp -f $@ /lib

.PHNOY:rebuild clean

rebuild:clean $(EXE)

clean:

rm -rf $(EXE) $(OBJS) $(LIBFUNCSO) $(LIBFUNCA)

(2)预定义变量

内部事先定义好的变量,但是它的值是固定的,并且有些的值是为空的。

变量

描述

AS

汇编程序,默认为as

CC

c 编译器默认为 cc

CPP

c 预编译器,默认为$(CC) -E

CXX

c++编译器,默认为 g++

RM

删除,默认为rm -f

ARFLAGS

库选项,无默认

ASFLAGS

汇编选项,无默认

CFLAGS

c 编译器选项,无默认

CPPFLAGS

c 预编译器选项,无默认

CXXFLAGS

c++编译器选项,无默认

根据内部变量,可以将makefile 改写为:

OBJS:=main.o func.o
#CC:=g++
main.exe:$(OBJS)$(CC) -o $@ $^
main.o:main.cpp$(CC) -o $@ -c $^
func.o:func.cpp$(CC) -o $@ -c $^ 

2)规则

分为:普通规则,隐含规则,模式规则。

(1)隐含规则:

例如:*.o 文件自动依赖*.c 或*.cc 文件,所以可以省略main.o:main.cpp 等。

OBJS := main.o fun.o
CFLAGS := -Wall –O2 -g
main.exe: $(OBJS)gcc $^ -o $@

(2)模式规则

通过匹配模式找字符串,%匹配 1 或多个任意字符串。

%.o: %.cpp 任何目标文件的依赖文件是与目标文件同名的并且扩展名为.cpp 的文件。

OBJS := main.o fun.o
CFLAGS := -Wall –O2 –g
main.exe : $(OBJS)gcc $^ -o $@
%.o: %.cpp                 #模式通配gcc -o $@ -c $^
另外还可以指定将*.o、 *.exe、 *.a、 *.so 等编译到指定的目录中:
DIR:=./Debug/
EXE:=main.exe
OBJS:=main.o
LIBFUNCSO:=libfunc.so
CFLAGS:= -fpic
$(DIR)$(EXE):$(DIR)$(OBJS) $(DIR)$(LIBFUNCSO)gcc -o $@ $< -L./ -lfunc
$(DIR)$(LIBFUNCSO):$(DIR)func.ogcc -shared -o $@ $^
$(DIR)main.o:main.cgcc -o $@ -c $^
$(DIR)func.o:func.cgcc $(CFLAGS) -c $^ -o $@
.PHONY:rebuild clean
rebuild:clean $(DIR)$(EXE)
clean:rm -rf $(DIR)*.o $(DIR)*.exe $(DIR)*.so

注意:当OBJS 里面有多项的时候,此时$(DIR)$(OBJS)只能影响到 OBJS 中第一个,后面的全部无效,因此需要全部列出来。

3)函数

(1)搜索文件函数wildcard

搜索当前目录下的文件名,展开成一列所有符合由其参数描述的文件名,文件间以空格间隔。

SOURCES = $(wildcard *.cpp)

//把当前目录下所有'.cpp'文件存入变量 SOURCES 里。

(2)字符串替换函数patsubst

格式:$(patsubst 要查找的子串,替换后的目标子串,源字符串)。

将源字符串(以空格分隔)中的所有要查找的子串替换成目标子串。

如:

OBJS = $(patsubst %.cpp,%.o,$(SOURCES))

把SOURCES 中'.cpp' 替换为'.o' ,然后把替换后的字符串存入变量 OBJS。

(3)加前缀函数addprefix

格式:$(addprefix 前缀,源字符串)

该函数把第二个参数列表的每一项前缀上第一个参数值。

1.5 make 的命令行选项

下一小节:linux静态库和动态库

相关内容

热门资讯

元旦主持词舞蹈串词 元旦主持词舞蹈串词  开场语:  华:尊敬的各位领导、各位来宾  蒋:亲爱的老师、同学们  杨:大家...
六一儿童节晚会主持词 六一儿童节晚会主持词(精选7篇)  随着六一儿童的临近,幼儿园在紧锣密鼓的为幼儿排练着各大节目,作为...
电视剧版《红高粱》中的经典台... 电视剧版《红高粱》中的经典台词  九儿:高粱下到锅里,蒸熟发酵大火灼烧,把酒气逼出来就成了酒了,你觉...
新学期欢迎新教师致辞 新学期欢迎新教师致辞(精选22篇)  在学习、工作乃至生活中,大家总免不了要接触或使用致辞吧,致辞要...
在新天地商场招商发布会上的致... 在新天地商场招商发布会上的致辞  在我们平凡的日常里,要用到致辞的情况还是蛮多的,致辞具有针对性,要...
主持词感恩的心开场白   主持词感恩的心开场白一  尊敬的各位领导、各位嘉宾、各位老师、亲爱的家长、同学们:  大家下午好...
签字仪式主持词 签字仪式主持词范文  篇一:项目签约仪式主持词  签约仪式主持词  尊敬的xxx,各位领导、各位来宾...
晚宴致辞 晚宴致辞(精选15篇)  在平平淡淡的学习、工作、生活中,要用到致辞的情况还是蛮多的,致辞受场合、事...
幼儿园大班毕业生家长会主持词 幼儿园大班毕业生家长会主持词(精选7篇)  主持词需要富有情感,充满热情,才能有效地吸引到观众。在各...
幼儿园六一文艺汇演主持词   1:尊敬的各位家长、  2:亲爱的小朋友们,  3:亲爱的爸爸妈妈、叔叔阿姨们  4:敬爱的老师...
同学聚会祝酒词 同学聚会祝酒词高中同学聚会祝酒词(1):斗转星移,岁月如歌,转眼我们从古龙中学毕业已经9多年了。9年...
台词经典语录 台词经典语录15篇  无论是在学校还是在社会中,许多人对一些广为流传的语录都不陌生吧,语录具有短小简...
幼儿园元旦晚会园长的经典致辞 幼儿园元旦晚会园长的经典致辞(精选5篇)  在平时的学习、工作或生活中,大家或多或少都用到过致辞吧,...
婚礼男方家长致辞 婚礼男方家长致辞通用15篇  无论在学习、工作或是生活中,大家都不可避免地会接触到致辞吧,致辞具有“...
学校班级元旦晚会主持稿 学校班级元旦晚会主持稿  导语:在学校召开元旦晚会的时候,通常要用到主持词的。接下来小编整理了学校班...
新郎迎娶新娘主持词 新郎迎娶新娘是一生中最浪漫的事情之一,那么都有什么好的主持词呢?以下是PINCAI小编整理的关于主持...
公司员工大会主持稿 公司员工大会主持稿  在现在的社会生活中,需要使用主持稿的情况越来越多,主持稿一般是由主持人根据场景...
开业的致辞 开业的致辞15篇  在日常的学习、工作、生活中,大家都对致辞很是熟悉吧,致辞是指在举行会议或某种仪式...
毕业聚餐主持词 毕业聚餐主持词  主持词是主持人在节目进行过程中用于串联节目的串联词。在当今中国社会,主持人在活动中...
女娲传说之灵珠经典台词 女娲传说之灵珠经典台词15句  你们根本不懂爱,你们的爱太过自私,不择手段。——仙乐  你放心,我不...