Makefile 快速入门
Linux & MAC(19) 
版权声明:本文为博主原创文章,未经博主允许不得转载。
终于答辩结束,有空来水水博客,今天总结一下Makefile中的常用规则,技巧,基本涵盖了日常应用, 如有不全希望大家留言添加~ 本文主要内容:
一. Makefile/makefile规则及举例
二. make的工作方式
三、makefile中的常用自动化变量与通配符
四、makefile自动生成依赖性关系
五、 调用命令
1. 显示命令
2. 命令出错
3. 命令执行
六、 变量
1. 变量定义
2. 变量引用
3. 变量替换
七、 条件判断
八、 常用函数
1. 字符串处理函数
2. 文件名操作函数
3. if
4. foreach
5. shell
九、 指定make的目标
更全更多文档请见《跟我一起写Makefile》陈皓78页的pdf。
一. Makefile/makefile规则及举例:
makefile由规则组成,每条规则告诉make两件事: 文件的依赖关系 & 如何生成目标文件。
e.g
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
# 定义变量, 反斜杠(\)是换行符的意思。
edit : $(objects)
# targets : prerequisites 冒号前表示目标文件, 冒号后为依赖文件(prerequisites)
cc -o edit $(objects)
# 编译命令, 每个target下都需要配一行command(使用了隐晦规则除外)
main.o : defs.h
# 本来是main.o: main.c defs.h, 根据make 的“隐晦规则”可以省略main.c,只列出其所需的头文件
# 根据make 的“隐晦规则”隐含了cc -c main.c
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
#.PHONY 意思表示 clean 是一个“伪目标”, 我们并不生成“clean”这个文件。 #可以用“make clean”运行“clean”这个目标。
clean :
rm edit $(objects)
二. make的工作方式:
1、读入所有的 Makefile。
2、读入被 include 的其它 Makefile。
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系和文件生成时间,决定哪些目标要重新生成。
7、执行生成命令。
三、makefile中的常用自动化变量与通配符:
makefile中支持的3个通配符: *,?,[...]
$@: 目标集
$<: 第一个依赖文件
$^: 所有依赖文件
$?: 所有比目标新的依赖集合
objects = *.o
objects := $(wildcard *.o)
四、自动生成依赖性关系
在Makefile中如果要对每个文件编写依赖关系会非常麻烦, 为了避免这个过程, 我们可以用c/c++编译器的"-M"功能, 即自动寻找源文件中包含的头文件, 并生成依赖关系。
如 cc -M Main.c 的输出是 main.o: main.c defs.h
PS:GNU的编译器(gcc/g++)需要用-MM参数, 如gcc -MM main.c, 不然"-M"会把一些标准库的头文件也引进来。
这部分内容我们就不详细讲了,因为在CoMake2中已经有了更好的集成。
五、 调用命令
1. 显示命令
@echo running...
这在调试整个make流程时很有用, 可以用make -n 或make --just-print之显示命令,但不执行命令。 也就是可以看到我们写的makefile真正执行起来的顺序流程。
2. 命令出错
忽略错误继续执行: make -k 或 make b--keep-going
全局忽略错误: make -i 或 make --ignore-errors
某一句忽略错误: 在前面加一个减号, 如-rm -f *.o
3. 命令执行
exec:
cd subdir; export variable=value;\ %将变量value以"variable"传递到subdir, 如果传递所有变量, 只需一个export就行
$(MAKE);\ % 嵌套执行make;
mkdir subsubdir
PS:make -w 可以查看当前工作目录
六、 变量
1. 变量定义:
大小写敏感
不许含有:,#,=,空格
变量声明时需要赋值,
用=幅值不一定是用已经幅好值的变量,也可以引用后面定义的变量;
用:=幅值, 只能引用已经幅值过的变量进行幅值;
赋值运算符A?=B表示, 若A被定义过,则不做,否则A赋值为B;
A+=B表示,变量幅值时字符串的追加;
2. 变量引用:
$(var)
3. 变量替换:
foo:= a.o b.o c.o
希望赋值bar为a.c, b.c, c.c, 有两种方法:
方法一: bar := $(foo:.o=.c)#将foo中所有以.o结尾的".o"字串全替换为".c"
方法二: bar := $(foo:%.o=%.c)
七、 条件判断
语法:
libs_for_gcc = -lgnu
ifeq($(UNAME),Linux)
LINUX := 1
else ifeq($(UNAME),Darwin)
OSX := 1
endif
类似地, 还有三个关键字: ifneq,ifdef和ifndef
注意,条件表达式中不要放自动化变量, 如$@,因为自动化变量只在运行时才有,而make在读取Makefile时就会根据条件表达式的值选择语句。
八、 常用函数
函数调用方法:
$(<function> <args>)
1. 字符串处理函数:
$(subst <from>,<to>,<text>) 将<text>中的<from>替换成<to>
$(patsubst <fromP>,<toP>,<text>) 将<text>中符合模式<fromP>的部分替换成<toP>
$(strip <text>) 去<text>中开头和结尾的空字符
$(findstring <find>,<from>) 在<from>中找<find>; 找到返回<find>, 否则返回空字符串
$(filter <pattern>,<text>) 从text中过滤出符合pattern模式的项
$(filter-out <pattern>,<text>) 反过滤
$(sort <list>) 排序
2. 文件名操作函数:
$(dir <text>) 取目录
$(suffix <text>) 取后缀名
$(addsuffix <suffix>,<names>) 加后缀
$(addprefix <prefix>,<names>) 加前缀
$(join <list1>,<list2>) list1, list2对应元素进行concatenate
3. if
$(if <condition>, <then>, <else>)
4. foreach
$(foreach <var>,<list>,<text>)
5. shell
执行shell命令
e.g $(shell find . -name '*.$(suffix_name)')
九、 常用指定make的目标功能:
all: 编译所有目标
clean: 删除所有被make创建的文件
install: 安装已编译好的程序, 就是将目标执行文件拷贝到指定目标中去
print: 列出改变了的源文件
tar: 把原程序打包备份为一个tar文件
参考材料: 《跟我一起写Makefile》
PS:其实还有别的参考,但是感觉这篇文档已经足够涵盖makefile常用内容了。
Makefile 快速入门的更多相关文章
- makefile快速入门
前言 在linux上开发c/c++代码,基本都会使用make和makefile作为编译工具.我们也可以选择cmake或qmake来代替,不过它们只负责生成makefile,最终用来进行编译的依然是ma ...
- Make 和 Makefile快速入门
前言 一个项目,拥有成百上千的源程序文件,编译链接这些源文件都是有规则的.Makefile是整个工程的编译规则集合,只需要一个make命令,就可以实现“自动化编译”.make是一个解释makefile ...
- Linux快速入门04-扩展知识
这部分是快速学习的最后一部分知识,其中最重要的内容就是源码的打包和软件的安装的学习,由于个人的Linux学习目的就是自己能在阿里云Ubuntu上搭建一个简单的nodejs发布环境. Linux系列文章 ...
- CMake快速入门教程-实战
http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/ http://blog.csdn.net/dbzhang800/article/detai ...
- 转:CMake快速入门教程-实战
CMake快速入门教程:实战 收藏人:londonKu 2012-05-07 | 阅:10128 转:34 | 来源 | 分享 0. 前言一个多月 ...
- Emacs快速入门
Emacs 快速入门 Emacs 启动: 直接打emacs, 如果有X-windows就会开视窗. 如果不想用X 的版本, 就用 emacs -nw (No windows)起动. 符号说明 C-X ...
- QuickJS 快速入门 (QuickJS QuickStart)
1. QuickJS 快速入门 (QuickJS QuickStart) 1. QuickJS 快速入门 (QuickJS QuickStart) 1.1. 简介 1.2. 安装 1.3. 简单使用 ...
- NOI Linux 快速入门指南
目录 关于安装 NOI Linux 系统配置 网络 输入法 编辑器 1. gedit 打开 配置 外观展示 2. vim 打开 配置 使用 makefile 编译运行 1. 编写 makefile 2 ...
- Web Api 入门实战 (快速入门+工具使用+不依赖IIS)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...
随机推荐
- Eclipse中的常用快捷键
快捷修复 Command+1 //int a=100L; //int a=(int) 100L; 快捷删除行 Command+D 快速起新行 Shift+Enter (当本行代码很长时,将光标定在本行 ...
- 【Same Tree】cpp
题目: Given two binary trees, write a function to check if they are equal or not. Two binary trees are ...
- Oracle中定义package以及存储过程的使用
使用scott账户下的dept表: select * from dept order by deptno; 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 S ...
- selenium--下拉列表选择
html 代码: <select name="ColumnId" id="columnOrd"> <option value="2& ...
- javascript进行url转义方法比较escape、encodeURI和encodeURIComponent
escape会将除了 ASCII 字母.数字和特定的符号(* @ - _ + . /)以外的字符全部进行转义编码,因此如果想对URL编码,最好不要使用此方法,因为它会让你的URL变的不可读. 提示:E ...
- 02.Hibernate映射基础
前言:Hibernate的核心功能是根据数据库到实体类的映射,自动从数据库绑定数据到实体类.使我们操作实体类(Java对象)就能对数据库进行增.删.查.改,而不用调用JDBC API使数据操作变得简单 ...
- poj 1815 Friendship 字典序最小+最小割
题目链接:http://poj.org/problem?id=1815 In modern society, each person has his own friends. Since all th ...
- Matlab动态数组实现
clear all; clc; a = []; %不是null,也不能什么都不是 for i=1:10 a = [a i]; end
- [bzoj 3226]校门外的区间
题意 输出最后的集合 题解 校门外的树会做吧 区间知道是什么东西吧 校门外的区间会做了吧 昨天做个大线段树没做出来,今天做个小线段树压压惊 py一下输入数据,然后操作变成: U 区间涂1 I 两侧 ...
- JavaScript之setcookie()讲解
function setcookie(name,value){ var Days = 30; var exp = new Date(); exp ...