makefile知识点归纳的
以一个样例開始,文件文件夹结构例如以下
---------(当前文件夹)-----------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
$(OBJS):%.o:%.cpp
$(OBJSDIR):
.PHONY:clean |
(一)makefile的规则
规则的基本格式:
TARGET... : DEPENDES...
|
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
|
上面makefile仅仅会编译add_int.cpp,假设要编译全部。能够加一个标签。
| OBJS=add_int.o add_float.o all:$(OBJS) $(OBJS):%.o:%.cpp
|
(三)搜索路径
指定须要搜索的文件夹后,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 ... >
|
target-parrtern是指明了targets的模式
prereq-parrterns是目标的依赖模式。它对target-parrtern形成的模式再进行一次依赖目标的定义。
样例:
| objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c
|
<target-parrtern>定义成“%.o”。意思是我们的<target>集合中都是以“.o”结尾的,而假设我们的<prereq-parrterns>定义成“%.c”,意思是对<target-parrtern>所形成的目标集进行二次定义,其计算方法是。取<target-parrtern>模式中的“%”(也就是去掉了[.o]这个结尾)。并为其加上[.c]这个结尾,形成的新集合。
(八)嵌套运行make
我们有一个子文件夹叫add。这个文件夹下有个makefile文件,来指明了这个文件夹下文件的编译规则。那么我们总控的Makefile能够这样书写:
subsystem:
|
等价于
subsystem:
|
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》http://blog.csdn.net/haoel
宋敬彬的《Linux网络编程》
makefile知识点归纳的的更多相关文章
- 【重走Android之路】【路线篇(二)】知识点归纳
[重走Android之路][路线篇(二)]知识点归纳 参考:http://blog.csdn.net/xujing81/article/details/7313507 第一阶段:Java面向对 ...
- makefile 学习归纳
makefile 学习归纳 一直希望 好好整理下 makefile的写法,这在linux编程界是必备技能.下面就好好的说道说道. 可以参考的大神总结 整理 makefile是供make命令执行的 脚本 ...
- 《零压力学Python》 之 第四章知识点归纳
第四章(决策和循环)知识点归纳 if condition: indented_statements [ elif condition: Indented_statements] [else: Inde ...
- 《零压力学Python》 之 第三章知识点归纳
第三章(第一个程序)知识点归纳 编程犹如写剧本.Python函数与剧本差别不大,你可以反复调用函数,而它每次都执行预定的“脚本”(脚本也可以指整个程序). 在Python IDLE中,真正的编程是从编 ...
- 《零压力学Python》 之 第二章知识点归纳
第二章(数字)知识点归纳 要生成非常大的数字,最简单的办法是使用幂运算符,它由两个星号( ** )组成. 如: 在Python中,整数是绝对精确的,这意味着不管它多大,加上1后都将得到一个新的值.你将 ...
- 《零压力学Python》 之 第一章知识点归纳
第一章(初识Python)知识点归纳 Python是从ABC语言衍生而来的 ABC语言是Guido参与设计的一种教学语言,为非专业编程人员所开发的. Python是荷兰程序员 Guido Van Ro ...
- Django知识点归纳总结之HTTP协议与URL
Django复习知识点归纳总结 1.HTTP协议 超文本传输协议(Hyper Text Transfer Protocol),是用于万维网服务器与本地浏览器之间的传输超文本的传送协议. HTT ...
- 给Java新手的一些建议----Java知识点归纳(J2EE and Web 部分)
J2EE(Java2 Enterprise Edition) 刚出现时一般会用于开发企业内部的应用系统,特别是web应用,所以渐渐,有些人就会把J2EE和web模式画上了等号.但是其实 J2EE 里面 ...
- 给Java新手的一些建议----Java知识点归纳(Java基础部分)
写这篇文章的目的是想总结一下自己这么多年来使用java的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享给刚刚入门的Java程序员和打算入Java开发这个行当的准新手们,希望可以给 ...
随机推荐
- [linux]chown和chmod命令
chown chown命令是将指定文件的拥有者改为指定的用户或组 例如: chown mail:mail test.log,把test文件指定拥有者和组都为mail chown -R mail:mai ...
- stripslashes和addslashes的区别
我们在向mysql写入数据时,比如: mysql_query(”update table set `title`=’kuhanzhu’s blog’”); 那就会出错.同asp时一样,数据库都会对单引 ...
- 【iOS开发-76】Private Contacts案例:导航控制器使用、数据传递、第三方类库使用、tableViewCell的加入删除、数据存储等
(1)效果 (2)源码与第三方类库下载 http://download.csdn.net/detail/wsb200514/8155979 (3)总结 --导航控制器,能够直接用代码的push和pop ...
- Codeforces 432D Prefixes and Suffixes(KMP+dp)
题目连接:Codeforces 432D Prefixes and Suffixes 题目大意:给出一个字符串,求全部既是前缀串又是后缀串的字符串出现了几次. 解题思路:依据性质能够依据KMP算法求出 ...
- Hasor:生命周期
首先引用Wiki的介绍一下Hasor: “Hasor是一款开源框架.它是为了解决企业模块化开发中复杂性而创建的.Hasor遵循简单的依赖.单一职责,在开发多模块企业项目中更加有调理.然而Has ...
- Http协议学习总结(转)
因为项目中很多地方都与Http协议有关,零散的了解了一下Http协议,但是没有系统的学习过. 今天根据网上其他同学的整理,加上我的一些经验,我也整理了一份.当做学习记录吧. 一.什么是HTTP协议 H ...
- 嗨翻C语言
<嗨翻C语言> 基本信息 作者: (美)David Griffiths Dawn Griffiths 译者: 程亦超 出版社:人民邮电出版社 ISBN:978711531884 ...
- J2EE互联网产品打造
CSDN的各位技术朋友们,你们好: 我司最近正在研发一套J2EE的互联网产品,前期功能设计例如以下: 1.权限管理 2.菜单管理 3.系统设置 4.页面管理[主要做静态化] 5.任务管理[数据同步以及 ...
- WPF自定义ListBox样式
<!--竖向--> <Style x:Key="ListBoxStyle1" TargetType="{x:Type ListBox}"> ...
- Linux系统时间和硬件时间设置
在Linux中有硬件时钟与系统时钟两种时钟.硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟.系统时钟则是指kernel中的时钟.所有Linux相关指令与函数都是读取系统时钟的设定 ...