1.概述

大型程序中,人们希望工具自动识别修改的文件,而且不需要输入冗长的命令,就可以进行编译链接等操作,于是make工程管理器应运而生。

  • make可以自动识别文件时间戳,只处理修改的文件;
  • make动作的依据是makefile文件

2 makefile基本结构

makefile通常包含:

  • target:需要make创建的目标体,通常为目标文件和可执行文件
  • dependency_file:target依赖的文件
  • command:创建target时需要执行的命令,此行必须用Tab开头
target:dependency_files
command /* 该行必须以Tab键开头,否则报错 */

举例说明:

#The simplest example
hello.o: hello.c hello.h
gcc -c hello.c -o hello.o

使用make target的形式:

make hello.o

一个稍微复杂一点的例子:

  • 有3个target,david、kang.o、yul.o,其中david依赖后面两个target
  • make david时,会执行下面的cmd,会一级一级向下检查
david:kang.o yul.o
gcc kang.o bar.o -o david
kang.o:kang.c kang.h head.h
gcc -Wall -O -g -c kang.c -o kang.o
yul.o:bar.c head.h
gcc -Wall -O -g -c yul.c -o yul.o

3 makefile变量

3.1 变量

挨个输入文件和编译选项比较麻烦,makefile支持用变量代替target、depandence、cmd以及其他部分。

分两种:

  • 递归展开方式 VAR=var,在引用处展开;需注意对自己的递归可能导致无限循环

    • 例如 CFLAGS = $(CFLAGS) -O,就会无限循环
  • 简单扩展方式 VAR := var,在定义处一次性展开

用变量重写上面的例子

OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g david:$(OBJS)
$(CC) kang.o bar.o -o david
kang.o:kang.c kang.h head.h
$(CC) $(CFLAGS) -c kang.c -o kang.o
yul.o:yul.c yul.h
$(CC) $(CFLAGS) -c yul.c -o yul.o

3.2 预定义变量

  • AR,库文件维护
  • AS,会便器
  • CC,C编译器
  • CPP,C预编译器
  • CXX,C++编译器
  • FC,Fortan编译器
  • RM,文件删除
  • ARFLAGS
  • ASFLAGS
  • CFLAGS
  • CPPFLAGS
  • CXXFLAGS
  • FFLAGS

3.3 自动变量

target和depandence已经出现了文件,后面可用自动变量替代这些文件,起到简化makefile的目的。

  • $* : 不包含扩展名的target文件名称
  • $+ : 所有的depandence文件,以空格分开,可能有重复
  • $< : 第一个depandence文件
  • $? : 所有时间戳比target晚的depandence文件
  • $@ : target文件的完整名称
  • $^ : 所有的depandence文件,以空格分开,不重复
  • $% : 如果目标文件是归档文件,则表示目标的归档成员名称

用自动变量重写刚才的例子:

OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g david:$(OBJS)
$(CC) $^ -o $@
kang.o:kang.c kang.h head.h
$(CC) $(CFLAGS) -c $< -o $@
yul.o:yul.c yul.h
$(CC) $(CFLAGS) -c $< -o yul.o

4 makefile规则

上述makefile写的比较全面,即显性方式。还支持隐形方式去掉,简化一些代码

4.1 隐含规则

只要告诉make目标文件,make会自动搜索隐含规则完成编译。

上述makefile可以进一步简化,省掉了最后两行,依赖中的kang.o yul.o,make会自动搜索kang.c和yul.c

隐含规则只能查找相同文件名,例如test.o会查找test.c

OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g david:$(OBJS)
$(CC) $(CFLAGS) $^ -o $@

常用的隐含规则:

  • C编译,.c编程.o:$(CC) -c $(CPPFLAGS) $(CFLAGS)
  • C++编译,.cc或.c编程.o:$(CC) -c $(CPPFLAGS) $(CXXFLAGS)
  • Pascal编译,.p编程.o:$(PC) -c $(PFLAGS)
  • Fortan编译,.r编程.o:$(FC) -c $(FFLAGS)

4.2 模式规则

定义相同处理规则的多个文件,文件必须用%开头

上述可改写为:

OBJS = kang.o yul.o
CC = gcc
CFLAGS = -Wall -O -g david:$(OBJS)
$(CC) $(CFLAGS) $^ -o $@
%.o:%.c
$(CC) -c $(CFLAGS) $< -o $@

5 make管理器的使用

  • -C dir : 读入指定目录下的makefile,变换目录
  • -f file : 读入file,作为makefile文件
  • -i : 忽略所有命令执行错误
  • -I dir : 指定被包含的makefile所在目录
  • -n : 只打印命令,但不执行
  • -p : 显示make变量数据库和隐含规则
  • -s : 在执行命令时不显示命令
  • -w : 如果make改变目录,则打印当前目录

附录1:gcc常用参数

  • -c :只编译,不链接,生成.o文件
  • -S :只编译,不汇编,生成汇编文件
  • -E :只进行预处理
  • -g :包含调试信息
  • -o file : 将file文件指定为输出文件
  • -v : 打印编译过程和版本
  • -I dir :在头文件搜索目录中增加dir目录

make工程管理器的更多相关文章

  1. Linux工程管理器——make

    一.定义 工程管理器,顾名思义,是指管理较多的文件 Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Make ...

  2. Makefile工程管理器及万能模板

    ​ Linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix程序员.在 Linux(unix )环境下使用GNU 的m ...

  3. Django 源码小剖: Django ORM 查询管理器

    ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...

  4. elecworks 图框管理器

    图框管理器中存储的是图纸模板(图框),新建图框的步骤如下: 1 数据库---图框管理器----新建 2 打开图框属性设置窗口,设置图框属性,设置好之后点击确定 3 右击图框图标---打开(进入图框绘制 ...

  5. Node.js包管理器:

    Node.js包管理器: 当我们要把某个包作为工程运行的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式安装 使用全局模式安装的包并不能直接在JavaScript文件中用require ...

  6. Django ORM 查询管理器

    Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...

  7. DLL何时需共享内存管理器

    Delphi创建DLL时,IDE自动生成的文档中写得很清楚,当在DLL中以动态数组或String做为参数或返回值时(即RTL自动维护的数据类型),请在每个工程文件的第一个单元加上ShareMem.这样 ...

  8. [Visual Studio] 记一次排错:打不开 Nuget 包管理器里的安装package页面,无法 安装 / 恢复 包

    出差一阵子PC很久没用了, 回来在用Visual Studio (2017) 的时候, 工程里无法安装Package了  >_<    --- 也不知道电脑做了什么?--- Nuget包管 ...

  9. WorldWind源码剖析系列:图层管理器按钮类LayerManagerButton和菜单条类MenuBar

    WorldWindow用户定制控件类中所包含的的可视化子控件主要有:图层管理器按钮类LayerManagerButton和菜单条类MenuBar.BmngLoader类中所包含的的可视化子控件主要有: ...

随机推荐

  1. 【1】hadoop搭建常用的Linux命令收集

    大数据学习第一步:Linux入门学习所需要的命令(非基础却常用) chmod u+x /filepath/../filename : u.g.o表示三个不同组,r.w.x表示可读可写可执行,+.-表示 ...

  2. 【Spring】Spring MVC高级技术

    前言 前面学习了简单的Spring Web知识,接着学习更高阶的Web技术. 高级技术 Spring MVC配置的替换方案 自定义DispatcherServlet配置 在第五章我们曾编写过如下代码. ...

  3. Java多线程学习之wait、notify/notifyAll 详解

    1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写. 2.wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关 ...

  4. [转载] Solr使用入门指南

    转载自http://blog.csdn.net/liuzhenwen/article/details/4060922 由于搜索引擎功能在门户社区中对提高用户体验有着重要的作用,在门户社区中涉及大量需要 ...

  5. SSM 配合 Mysql 数据库和代码数据源主从分离

    大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢 ...

  6. 自定义统一api返回json格式(app后台框架搭建三)

    在统一json自定义格式的方式有多种:1,直接重写@reposeBody的实现,2,自定义一个注解,自己去解析对象成为json字符串进行返回 第一种方式,我就不推荐,想弄得的话,可以自己去研究一下源码 ...

  7. 深入理解ES6之——迭代器与生成器

    迭代器 迭代器是被设计专用于迭代的对象,带有特定接口.所有的迭代器对象都有next方法,会返回一个结果对象.该结果对象有两个属性:对应下一个值的value,以及一个布尔类型的done,其值为true时 ...

  8. 关于iOS GangSDK的使用,为App快速集成社群公会模块

    手上有一个自己开发的小游戏,想加一个家族系统活跃下游戏的氛围,想到这块儿可能会有大量的工作需要自己做,就偷了个懒去网上搜罗了一波,结果惊奇的发现居然真的有类似的服务,并且还是免费的,所以决定入坑尝试一 ...

  9. vim操作命令

    一,命令模式下 文件顶部: gg 文件底部: G 删除当前行:dd 删除当前行,并进入INSERT模式: cc 取消删除:u

  10. Kafka设计解析(八)- Exactly Once语义与事务机制原理

    原创文章,首发自作者个人博客,转载请务必将下面这段话置于文章开头处. 本文转发自技术世界,原文链接 http://www.jasongj.com/kafka/transaction/ 写在前面的话 本 ...