第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静态库和动态库

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...