博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
makefile知识点归纳的
阅读量:6432 次
发布时间:2019-06-23

本文共 3691 字,大约阅读时间需要 12 分钟。

以一个样例開始,文件文件夹结构例如以下

---------(当前文件夹)-----------main.c

                  |

                  |--------add文件夹

                  |               |-------add_int.cpp

                  |               |-------add_float.cpp

                  |

                  |--------sub文件夹

                                 |--------sub_int.cpp

                                 |--------sub_float.cpp


makefile文件例如以下:

#example 
CXX=g++
CXXFLAGS=-Iadd -Isub
OBJSDIR=.objs
VPATH=add:sub:.
OBJS=add_int.o add_float.o sub_int.o sub_float.o \
main.o
TARGET=cacu
$(TARGET):$(OBJSDIR) $(OBJS)
$(CXX) $(OBJSDIR)/*.o $(CXXFLAGS) -o $@
$(OBJS):%.o:%.cpp
$(CXX) $< $(CXXFLAGS) -c -o $(OBJSDIR)/$@
$(OBJSDIR):
mkdir -p ./$@
.PHONY:clean
clean:
-$(RM) $(TARGET)
-$(RM) $(OBJSDIR)/*.o

(一)makefile的规则

规则的基本格式:

TARGET... : DEPENDES...
COMMAND
...
TARGET:规则所定义的目标。能够是Object File。也能够是运行文件。还能够是一个标签(Label)。

DEPENDES:运行此规则所必须的依赖条件。


COMMAND:规则所运行的命令(随意的shell命令)。


1.命令行必须以一个Tab键開始。

2.凝视用“#”字符。


3.用反斜杠(\)能够将较长的行分解为多行。


(二)make是怎样工作的

1.make会在当前文件夹下找名字叫“Makefile”或“makefile”的文件。

2.假设找到。它会找文件里的第一个目标文件。并把这个文件作为终于的目标文件。定义在Makefile中的目标可能会有非常多,可是
第一条规则中的目标将被确立为终于的目标。假设第一条规则中的目标有非常多个,那么第一 个目标会成为终于的目标。


3.make会一层又一层地去找文件的依赖关系,直到终于编译出第一个目标文件。

比如

OBJS=add_int.o add_float.o
$(OBJS):%.o:%.cpp
$(CXX) $< -c -o $@
上面makefile仅仅会编译add_int.cpp,假设要编译全部。能够加一个标签。

OBJS=add_int.o add_float.o
all:$(OBJS)
$(OBJS):%.o:%.cpp
$(CXX) $< -c -o $@
   

(三)搜索路径

指定须要搜索的文件夹后,make会自己主动找到指定文件的文件夹并加入到文件上。有两种指定搜索文件夹的方法.

方法一:

VPATH=path1:path2: ...
比如

VPATH=add:sub:.

add_int.o:%.o:%.cpp

$(CXX) $< -c -o $@
会自己主动扩展成

add_int.o:
add/
add_int.cpp

g++ 
add/add_int.cpp -c -o add_int.o

方法二:

vpath <pattern> <directories>
为符合模式<pattern>的文件指定搜索文件夹<directories>。

比如:

vpath %.h ../headers

make会在“../headers”文件夹下搜索全部以“.h”结尾的文件。


(四)伪目标

.PHONY:name
当运行“make name”时一定是运行makefile中的这个伪目标,而无论是否存在一个叫name的文件。


(五)makefile中的部分提前定义变量

 变量名  含义  默认值
 CC C语言编译器的名称  cc
 CXX C++ 语言编译器的名称  g++
 CFLAGS C语言编译器的编译选项  无
 CXXFLAGS C++语言编译器的编译选项  无
 RM  删除文件程序的名称  rm -f
   

(六)makefile中的自己主动变量

 变量  含义
 $@  目标项中目标文件的名称
 $<  依赖项中第一个依赖文件的名称
 $^  全部不反复的依赖文件
 $*  目标文件的名称,不包括扩展名
 $?

 依赖项中,全部目标文件时间戳晚的依赖文件
   

(七)静态模式

 < targets ... >: < target-pattern >: < prereq-patterns ... >
<command>
target-parrtern是指明了targets的模式

prereq-parrterns是目标的依赖模式。它对target-parrtern形成的模式再进行一次依赖目标的定义。

样例:

objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $<  -o $@
<target-parrtern>定义成“%.o”。意思是我们的<target>集合中都是以“.o”结尾的,而假设我们的<prereq-parrterns>定义成“%.c”,意思是对<target-parrtern>所形成的目标集进行二次定义,其计算方法是。取<target-parrtern>模式中的“%”(也就是去掉了[.o]这个结尾)。并为其加上[.c]这个结尾,形成的新集合。


(八)嵌套运行make

我们有一个子文件夹叫add。这个文件夹下有个makefile文件,来指明了这个文件夹下文件的编译规则。那么我们总控的Makefile能够这样书写:

subsystem:
cd add && $(MAKE)
等价于

subsystem:
$(MAKE) -C add

1.假设你要让上一条命令的结果应用在下一条命令时,你应该使用分号(;)分隔这两条命令。或者使用“&&”。

2.假设你要传递变量到下级Makefile中,那么你能够使用这种声明:

 export < variable ... >
须要注意的是。有两个变量,一个是SHELL。一个是MAKEFLAGS,这两个变量无论你是否export,其总是要传递到下层makefile中。



(九)变量

变量在声明时须要给予初值,而在使用时。须要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包含起来。


1.当使用一个变量来定义还有一个变量时须要注意:

foo=$(bar)
bar=hello world!
使用“=”号时。右側变量的值能够定义在文件的不论什么一处。也就是说,右側中的变量不一定非要是已定义好的值,其也能够使用后面定义的值。

bar=hello world!
foo:=$(bar)
使用":="号时,前面的变量不能使用后面的变量,仅仅能使用前面已定义好了的变量。



2.空格

nullstring:=
space:=$(nullstring) # end of the line
dir:=/foo/bar    # directory to put the frobs in
nullstring 是一个Empty变量,当中什么也没有,而我们的space的值是一个空格。採用“#”凝视符来表示变量定义的终止。


dir这个变量的值是“/foo/bar    ”,后面跟了4个空格。


3.变量的静态模式

foo:=a.o b.o c.o
bar:=$(foo:%.o=%.c)
$(bar)变量的值为“a.c b.c c.c”。


4.变量的追加

objects=main.o foo.o bar.o utils.o
objects+=another.o
   

(十)隐含规则

对一个目标文件是“文件名称.o”,依赖文件是“文件名称.c"的规则,能够省略其编译规则的命令行。

由于假设make找到一个whatever.o。那么whatever.c,就会是whatever.o的依赖文件。而且 cc -c whatever.c 也会被推导出来。这样就能够省略掉描写叙述.c文件和.o依赖关系的规则,而
仅仅须要给出那些特定的规则描写叙述(.o目标所须要的.h文件)


1.编译C程序的隐含规则

“filename.o”的目标的依赖目标会自己主动推导为“filename.c”,而且其
生成命令是“$(CC) –c $(CXXFLAGS) $(CFLAGS)”


2.编译C++程序的隐含规则

“filename.o”的目标的依赖目标会自己主动推导为“filename.cc”或是“filename.C”,而且其
生成命令是“$(CXX) –c $(CXXFLAGS) $(CFLAGS)”


參考:

陈皓的《跟我一起写 Makefile》

宋敬彬的《Linux网络编程》

转载地址:http://wwxga.baihongyu.com/

你可能感兴趣的文章
IDEA+Maven+Tomcat构建项目流程
查看>>
数据是重要的战略资源,数据同样是产品非常重要的组成部分。淘宝对中国最大的贡献,不只是方便了老百姓购物,而是把中国消费者的消费习惯数据慢慢沉淀下来。...
查看>>
Leetcode Find Minimum in Rotated Sorted Array
查看>>
Python接口测试-使用requests模块发送post请求
查看>>
System.currentTimeMillis()计算方式与时间的单位转换
查看>>
Extra:Variable Types
查看>>
js传参时,没有参数传入,默认值的设置
查看>>
ASP.NET温故而知新学习系列之ASP.NET多线程编程—.NET下的多线程编程Thread中委托的使用(六)...
查看>>
最新整理知识结构图
查看>>
linux安装mysql
查看>>
flask 2 进阶
查看>>
sentences in movies and teleplays[1]
查看>>
【20181023T1】战争【反向并查集】
查看>>
win7网络共享原来如此简单,WiFi共享精灵开启半天都弱爆了!
查看>>
iOS9 未受信任的企业级开发者
查看>>
paper 40 :鲁棒性robust
查看>>
优化MySchool数据库(事务、视图、索引)
查看>>
使用笔记:TF辅助工具--tensorflow slim(TF-Slim)
查看>>
大话设计模式读书笔记3——单例模式
查看>>
实验三
查看>>