学习GNU Make (1)(转)
在众多的make版本中, GNU make是最突出的, 它已成了当前的"标准"make. 所有的GNU/Linux平台上都有提供, 一些BSD的变种, Mac OS X甚至cygwin也都使用GNU Make. 所以选择GNU make学习, 编写makefile是不二选择.
关于GNU Make, 可以看看这篇文章 . 它摘录自 o'reilly的《GNU Make项目管理》, 这本书china-pub上有得卖, 薄薄280面, 定价却要¥58, 在此鄙视一下东南大学出版社
OK, 现在步入正题, 这里假设你使用C语言进行编程.
预备知识
首先我们必须具有一些预备知识: 你知道什么叫编译, 什么叫连接吗? 目标文件和可执行文件有什么区别? 一个C源程序是如何转化为可执行程序的? 以往的IDE往往对C初学者隐藏了这些基础概念. 要使用Make, 这些概念是要清楚的.
另外, 你需要对GNU/Linux上的编译器具有一定的了解——当然是gcc啦! 因为Makefile中的命令实际上是针对编译器的命令.
可以参考本人blog的这两篇文章:
GNU/Linux平台的C程序开发及程序运行环境
GCC笔记
几个要说明的词汇
目标(target): 在makefile指定要生成的目标, 它可以是可执行文件, 目标文件, 也可以只是一个标签.
先决条件(prerequisite): makefile中指定的针对要生成某个target所依赖的文件或标号.
命令(command): Make针对target利用makefile中指定的规则所调用的命令. 它可以是你在shell中能够指定的所有命令.
GNU Make的工作原理
Make 通过 makefile文件被告知它的工作: 要生成怎样的目标文件? 由哪些代码编译生成?所以学习GNU Make实际上就是学习Makefile的写法. 下面是一个简单的makefile:
hello: hello.c gcc hello.c -o hello |
我们熟悉的hello程序,
$ make
gcc hello.c -Wall -o hello
这样我们的hello可执行程序就出来了!
make的规则: target: prereq1 prereq2 commands |
target就是目标文件 , 它可能是,o文件, 可执行文件或标签中的一种.
关于target,有这样的约定:
如果某target被包含在执行make的命令行参数中, 则更新该target; 如果make没带参数, 则将第一个target作为默认目标进行更新.
prerequisites是生成target所需要的文件.
command是make调用gcc执行的指令. 注意, command以Tab键打头 , 不能是空格!
到了这里, 就可以理解Make的原理了:
make的基本思想: 对于一个target (由命令行所指定或默认第一个target), 如果它不存在, 或者它的prerequisites中有比它更新的, 那么执行command所指定的命令. 所谓"更新", 是指比别的文件更晚被修改, make通过timestamp来记录谁更新. |
makefile文件名
默认情况下, make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件.
最好不要用“GNUmakefile”, 这个文件只被GNU make识别. 虽然有些Make只对全小写的“makefile”文件名敏感, 但大多数的make都支持“makefile”和“Makefile”这两种默认文件名.
可以使用别的文件名来书写makefile, 比如: "Make.Linux", “Make.Solaris”, “Make.AIX”等. 如果要指定特定的Makefile,你可以使用make的“-f”或者“--file”参数,如:make -f Make.Linux 或 make --file Make.AIX.
推荐以 Makefile 作为文件名! |
命令行中调用Make命令
(1) $ make target-name
(2) $ make
(3) $ make non-exist-target
(4) $ make -n or $ make --just-print
(1) 如果在命令行中指定了target, 则make针对该target进行工作
(2) 如果未指定target, 则make对默认target进行操作.(Makefile中出现的第一个target)
(3) 如果指定的target不存在, 则make报错:
make: *** No rule to make target `non-exist-target'. Stop.
(4) 若加上 -n 或者 --just-print选项, make只是列出将要执行的命令, 并不执行它们. 这非常有用!
Makefile 的基本语法
Makefile 采用自上而下 (top-down)的组织, 最开始的target即"终极目标", 也是默认target. 观察make输出的命令可以发现, 它们的顺序与出现在Makefile中的命令刚好相反. 可以把Makefile中针对target的规则想象成C函数. 最开始的是main(), 然后依次调用相关的函数(即针对prereq调用相关的规则).
看看一个比较简单的Makefile规则:
target1 target2 target3 : prereq1 prereq2 command1 command2 command3 |
第一行列出了targets和prereqs, 注意目标与它们依赖的文件之间以" : "分隔. 目标或prereq之间以空格分隔.
在冒号左边可以有1个或多个targets, 在冒号右边可以有0个或者多个prerequisites. 如果prerequisite的数目为0, 则只有当对应的target不存在时才执行命令.
如果command不和目标, 先决条件在一行,那么它之前必须以Tab开头; 如果command与目标, 先决条件在一行, 那么它要以";"开头. Make将command传递给子shell去执行.
注意: 不要忘了在命令以Tab开头, 也别在不是命令开头的地方输入Tab, 否则Make会将它之后的字符当作命令. |
Make中的注释符为 "#". #之前可以有空格, 从#开始到行尾的所有字符都会被忽略. 注意: 如果你把#写在了命令中, 包括#在内的行都会传递给shell, 会有什么样的结果取决于你所用的shell.
可以在Makefile中使用转义字符 /, 我们都知道, 在命令行中, 可以使用 / 在下一行输入命令. 同样的, 在Makefile的所有行中, 都可以使用 / 来分割太长的语句.
学习GNU Make (1)(转)相关推荐
- 学习GNU Emacs命令速查表(三)
博客地址:http://blog.csdn.net/shuxiao9058 原始作者:季亚 第八章简章的文字排版和特效编辑 表8-1:制表位命令速查表 键盘操作 命令名称 动作 (无) edit-ta ...
- linux arm 汇编学习,如何在LINUX平台上学习GNU ARM汇编
本例说明如何在LINUX平台上学习GNU ARM汇编. 1.软件环境 vmware 5.0 + redhat 9.0 + skyeye 1.2.4 + arm-elf 工具 2. 源文件 a.s -- ...
- 学习GNU Make (2): 规则
Makefile中指定了针对某个target的规则(rule). 注意Makefile中可以有多条规则: 即针对Makefile中的一条targets, prerequisites列表, 就有一条对应 ...
- ARM学习-GNU ARM汇编
目录 1.GNU汇编语言语句格式 2.汇编程序中的标号symbol(或label) 3.GNU汇编程序中的分段 3.1 .section伪操作 3.2 汇编系统预定义的段名 4.GNU汇编语言定义入口 ...
- USRP调研及学习(GNU Radio)
USRP(Universal Software Radio Peripheral,通用软件无线电外设)可以使普通计算机能像高带宽的软件无线电设备一样工作.从本质上讲,USRP充当一个无线电通讯系统的数 ...
- TQ2440开发板学习纪实(0.1)--- GNU Freestanding(Naked)C ARM交叉开发环境创建与测试
0 由来 在我的博文 GNU ARM交叉汇编环境的搭建与测试中,详细讲解了GNU ARM汇编环境的创建与使用方法.实际开发中,直接使用汇编语言写的代码往往很少,尽在系统启动和性能要求极其苛刻的时候才会 ...
- 介绍使用 GNU Screen 的小技巧
学习基本的 GNU Screen 终端复用技术,然后下载我们的终端命令备忘录,以便你能够熟悉常用的快捷方式. 学习基本的 GNU Screen 终端复用技术,然后下载我们的终端命令备忘录,以便你能够熟 ...
- 嵌入式系统开发-学习路线
嵌入式系统开发 课程链接 随着嵌入式设备的普及,嵌入式应用的需求量也随之增大,本课程将重点培养基于linux系统下的嵌入式应用开发,包括5个阶段,其中课程涵盖了linux系统下的多进程.多线程嵌入式开 ...
- 让这世界再多一份GNU m4 教程 (全文整理)
作者:garfileo 作者主页 本文整理自:https://segmentfault.com/a/1190000004104696 整理者:Timekeeperl csdn博客 欢迎转载!请 ...
最新文章
- HDU-1268 找新朋友 (素数筛选)
- 这个GAN没见过猪,却能把狗变成猪
- Spark读取MySQL中的数据为DataFrame
- jBPM 流程设计器和查看【包括Web形式】的总结
- 128位java_求一个java算法,用128位密钥的AES加密128位明文,得出的密文还是128位...很着急,非常感谢各位大神,求救!...
- Python基础01-变量及数据类型
- Elasticsearch环境搭建和介绍(Windows)
- 热图绘制一个快乐五一
- 记录一次分组求和查询优化
- 使用mvc时,在视图view中使用强类型视图,在web.config文件中添加命名空间namespace的引用不起作用,解决方法...
- fedora 安装chrome
- 用亿图软件怎么画数据模型图?
- python httpserver 支持ipv6
- 怎么用爬虫筛选简历_筛选数据分析师简历全流程
- C++控制输出对齐---setw()函数
- 进入IT行业,你后悔过吗?
- golang做php的中间件,Golang 之 中间件
- vue 微信公众号定位+高德地图
- 尝试使用sklearn自动进行多模型预测并计算权重
- 2017美国计算机专业排名,2017年美国大学计算机专业排名TOP121