Makefile规则

target ... :prerequisites...
command target就是一个目标文件,可以是object file,也可以是可以执行文件,也可以是一个标签 prerequisites就是要生成那个target所需要的文件或者目标文件 command就是make执行的命令的,任意的shell命令
target依赖于prerequisites,其生成规则定义在command中。
prerequisites中如果有一个规则以上的文件比target文件要新的话,command锁定义的命令就会被执行。

例子1

[root@typhoeus79 makefile]# ll
total 16
-rw-r--r-- 1 root root 69 Jun 20 11:27 head.c
-rw-r--r-- 1 root root 45 Jun 20 11:27 head.h
-rw-r--r-- 1 root root 150 Jun 20 11:30 Makefile
-rw-r--r-- 1 root root 81 Jun 20 11:28 test.c
------------------------------------------------------------------------
[root@typhoeus79 makefile]# more head.h
#include <stdio.h> void printword(char *s);
[root@typhoeus79 makefile]# more head.c
#include "head.h" void printword(char *s)
{
printf("%s\n",s);
}
[root@typhoeus79 makefile]# more test.c
#include "head.h" int main()
{
char *s="Hello world!"; printword(s);
}
[root@typhoeus79 makefile]# more Makefile
test: test.o head.o
gcc -o test test.o head.o head.o: head.c head.h
gcc -c head.c
test.o: test.c
gcc -c test.c clean:
rm -rf test.o head.o test

  

make是如何工作的

在默认的情况下,只输入make命令,那么:

1、make会找在当前目录下名字为makefile或者Makefile文件;

2、如果找到,它会找第一个目标文件,例如上面例子中的test文件,并把这个作为最终的目标文件

3、如果test目标文件不存在,或者edit所依赖的后面的.o文件的文件修改时间要比test文件新,那么就会执行后面所定义的命令生成test这个文件

4、如果test所依赖的.o文件也不存在,那么make会在当前文件中找目标文件为.o的文件依赖性,如果找到再根据类似3生成.o文件

整个make的依赖性,make会一层一层地区找文件的依赖关系,直到最终编译出第一个目标文件。

makefile中使用变量

PROJECT_NAME = "sqlparser"
VERSION = "2.3.0"
LDFLAGS = -lz -lm -lpthread -lcrypt -lcrypto
CFLAGS = -fPIC -Wall -W -pipe -Wno-unused-parameter -g -Wswitch -Wpointer-arith -Wredundant-decls -Wformat -D_GNU_SOURCE
OBJS = sql_parse.o sql_lex.o \
sql_select.o sql_insert.o sql_update.o sql_delete.o sql_replace.o sql_set.o sql_ddl.o sql_create_table.o sql_alter_table.o \
sql_partition.o sql_define.o sql_show.o sql_util.o sql_transaction.o sql_dml.o sql_prepared.o
TARGET = sample libsqlparse.a
LIBDIR = ./output/
CC = gcc

声明一个变量objects,通过$(objects)的方式来使用这个变量,改良版的makefile如下:

[root@typhoeus79 makefile]# more Makefile
OBJS = test.o head.o
CC = gcc test: $(OBJS)
$(CC) -o test test.o head.o head.o: head.c head.h
gcc -c head.c
test.o: test.c
gcc -c test.c clean:
rm -rf test.o head.o test
[root@typhoeus79 makefile]# make clean
rm -rf test.o head.o test
[root@typhoeus79 makefile]# make
gcc -c test.c
gcc -c head.c
gcc -o test test.o head.o

 make自动推导

make可以自动推动文件以及文件依赖关系后面的命令

只要make看到一个[.o]文件,会自动把[.c]文件加到依赖关系,并且对于的cc -c [.c]也会被推动出来

对应上面的makefile继续被修改为

[root@typhoeus79 makefile]# make clean
rm -rf test.o head.o test
[root@typhoeus79 makefile]# make
gcc -c -o test.o test.c
gcc -c -o head.o head.c
gcc -o test test.o head.o
[root@typhoeus79 makefile]# more Makefile
OBJS = test.o head.o
CC = gcc test: $(OBJS)
$(CC) -o test test.o head.o head.o: head.h clean:
rm -rf test.o head.o test

隐晦规则

.PHONY: clean
clean:
rm -rf test.o head.o test

.PHONY表示clean是个伪目标文件
另类风格的makefile

make可以自动推导命令,看到那堆[.o]和[.h]的依赖不爽,重复的[.h]是否可以收拢起来?

[root@typhoeus79 makefile]# more Makefile
OBJS = test.o printInt.o printWord.o
CC = gcc test: $(OBJS)
$(CC) -o test $(OBJS) $(OBJS): printWord.h
printWord.o:printInt.h .PHONY: clean
clean:
rm -rf $(OBJS) test
[root@typhoeus79 makefile]# make
gcc -c -o test.o test.c
gcc -c -o printInt.o printInt.c
gcc -c -o printWord.o printWord.c
gcc -o test test.o printInt.o printWord.o

这种风格,使得makefile简单,但是文件依赖关系显得凌乱,依赖关系看不清楚,对于文件多,不合适。

[root@typhoeus79 makefile]# more Makefile
OBJS = test.o printInt.o printWord.o
CC = gcc test: $(OBJS)
$(CC) -o test $(OBJS) test.o:printWord.h printWord.o:printInt.h .PHONY: clean
clean:
rm -rf $(OBJS) test
[root@typhoeus79 makefile]# make
gcc -c -o test.o test.c
gcc -c -o printInt.o printInt.c
gcc -c -o printWord.o printWord.c
gcc -o test test.o printInt.o printWord.o

 清空目标文件的规则

每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,不仅便于重编译,也很利于保持文件的清洁。

.PHONY: clean
clean:
rm -rf $(OBJS) test

更稳健的方式,.PHONY意思clean是一个伪目标,在rm命令前面加一个小减号的意思,也许某些文件出现问题,但不要管,继续做后面的事情。

clean规则不要放在文件的开头,不然,就会变成make的默认目标。

不成文的规矩,clean从来都是放在文件的最后。

错误的例子:

.PHNOY: clean
clean:
rm -rf printInt.o

clean是目标对象,一定不能加[Tab]键,否则出错:

[root@typhoeus79 makefile]# make -f testMakefile clean
make: *** No rule to make target `clean'. Stop.

Makefile例子引入的更多相关文章

  1. Spring框架系列(2) - Spring简单例子引入Spring要点

    上文中我们简单介绍了Spring和Spring Framework的组件,那么这些Spring Framework组件是如何配合工作的呢?本文主要承接上文,向你展示Spring Framework组件 ...

  2. Makefile的引入及规则

    ARM裸机1期加强版视频课程配套WiKi第9课第5节_Makefile的引入及规则. 文字不能完全替代视频,所以如果你看了这些文章不太懂,建议购买视频进一步学习. 视频购买地址:100ask.taob ...

  3. makefile例子《一》

    一.例子 (1)makefile和src源文件不在同一目录下 (2)把.o生成到指定目录下 文件结构目录 ----inc      //放头文件 ----lib //放所需要的.a或者.so文件 -- ...

  4. 一个通用的两级Makefile例子

    目的 进行如项目的顶层目录后,运行make,即可直接编译项目中所有的源文件,并生成最终的可执行文件 实现头文件自动依赖 添加源文件不用修改Makefile,且可以自动编译新文件 顶层目录下添加文件夹, ...

  5. Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入)

    一.确认已经装好了GCC和Make的软件包 可以使用whereis命令查看: 如果whereis  gcc和whereis  make命令有结果,说明安装了这两个软件,可以继续往下做. 二.使用GCC ...

  6. AngularJS2.0 hello world例子——引入这么多额外的依赖库真是很忧伤啊

    初识Angular2 写一个Angular2的Hello World应用相当简单,分三步走: 1. 引入Angular2预定义类型 import {Component,View,bootstrap} ...

  7. Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入) 转

    http://www.crazyant.net/2011/10/29/linux%E4%B8%8Bgcc%E5%92%8Cmakefile%E5%AE%9E%E4%BE%8B%EF%BC%88%E4% ...

  8. (二十一)Makefile例子

    ROOT_PROJECT = .DIR_INC = -I$(ROOT_PROJECT)/include -I$(ROOT_PROJECT)/include/NE10 DIR_BIN = $(ROOT_ ...

  9. [编译] 1、第一个makefile简单例子

    前言 本篇用一个最简单的例子引入makefile,教你编写第一个makefile 正文 在Download/aa文件夹下有a.c和makefile文件 litao@litao:~/Downloads/ ...

随机推荐

  1. ASP.NET没有魔法——ASP.NET MVC 与数据库之EntityFramework配置与连接字符串

    前几篇文章中介绍了如何使用Entity Framework来操作数据库,但是对EF的配置.连接字符串的指定仍然存在一些疑问. 本章将对EF的配置进行介绍. EF可以通过两种方式来实现配置,分别是代码方 ...

  2. SQL查询和删除重复字段的内容

    --例如: id NAME VALUE 1 a pp 2 a pp 3 b iii 4 b pp 5 b pp 6 c pp 7 c pp 8 c iii --id是主键 --要求得到这样的结果 id ...

  3. Echarts数据可视化series-effectscatter特效散点图,开发全解+完美注释

    全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...

  4. iOS的异步绘制--YYAsyncLayer源码分析

    iOS的异步渲染 最近看了YYAsyncLayer在这里总结一下.YYAsyncLayer是整个YYKit异步渲染的基础.整个项目的Github地址在这里.你可以先下载了一睹为快,也可以跟着我一步一步 ...

  5. TypeScript中的怪语法

    TypeScript中的怪语法 如何处理undefined 和 null undefined的含义是:一个变量没有初始化. null的含义是:一个变量的值是空. undefined 和 null 的最 ...

  6. 关于keyTyped

    蠢了,重写keyTyped方法时候拿keyCode去做比较....记一下....VK_UNDEFiEND.......

  7. JSP前后台数据交互

    1.一般方法:在页面加载时载入数据 首先,新建一个包,在包内创建一个类,类实现接口Servlet-javax.servlet 然后,在web.xml文件里配置如下 <?xml version=& ...

  8. Unix时代的开创者Ken Thompson

    自图灵奖诞生以来,其获得者一直都是计算机领域的科学家与学者,而在所有这些界的图灵奖中只有唯一的一届有个例外,那就是Ken Thompson与Dennis M. Ritchie,他们都是计算机软件工程师 ...

  9. 局部刷新Ajax

    1.1.1  Ajax的由来: 如下注册界面 界面在注册的时候,需要用户输入的信息有很多,假如我们将所有的数据都录入后,在点击会员注册按钮,然后将整个页面数据进行提交,此时如果该用户名已经被占用,那么 ...

  10. 使用PHPExcel-1.8实现导入

    //使用PHPExcel-1.8实现导入(下载PHPExcel-1.8):导入excel 后缀名必须是.xls1.<form method="post" action=&qu ...