07makefile文件
makefile
- 规则:
目标: 依赖
(tab)命令
第一个版本:
main: main.c fun1.c fun2.c sum.c
gcc -o main main.c fun1.c fun2.c sum.c
第二个版本:
检查规则:
要想生成目标文件, 先要检查依赖条件是否都存在:
若都存在, 则比较目标时间和依赖的时间, 如果依赖的时候比目标的时间新,
则重新生成目标; 否则不重新生成
若不存在, 则往下找有没有生成依赖的规则, 有则生成, 如果没有则报错.
- 例子
main:main.o fun1.o fun2.o sum.o
gcc -o main main.o fun1.o fun2.o sum.o
main.o:main.c
gcc -o main.o -c main.c -I./
fun1.o:fun1.c
gcc -o fun1.o -c fun1.c
fun2.o:fun2.c
gcc -o fun2.o -c fun2.c
sum.o:sum.c
gcc -o sum.o -c sum.c
第三个版本:
普通变量
* 变量定义直接用 =
* 使用变量值用 $(变量名)
如:下面是变量的定义和使用
foo = abc // 定义变量并赋值
bar = $(foo) // 使用变量, $(变量名)
定义了两个变量: foo、bar, 其中bar的值是foo变量值的引用。
除了使用用户自定义变量, makefile中也提供了一些变量(变量名大写)供用户直接使用, 我们可以直接对其进行赋值:
CC = gcc #arm-linux-gcc
CPPFLAGS : C预处理的选项 -I
CFLAGS: C编译器的选项 -Wall -g -c
LDFLAGS : 链接器选项 -L -l
自动变量
* $@: 表示规则中的目标
* $<: 表示规则中的第一个条件
* $^: 表示规则中的所有条件, 组成一个列表, 以空格隔开, 如果这个列表中有重复的项则消除重复项
特别注意:自动变量只能在规则的命令中使用.
模式规则
至少在规则的目标定义中要包含’%’, ‘%’表示一个或多个, 在依赖条件中同样可以使用’%’, 依赖条件中的’%’的取值取决于其目标:
比如: main.o:main.c fun1.o: fun1.c fun2.o:fun2.c, 说的简单点就是: xxx.o:xxx.c
变量:
自定义变量: var = hello, $(var)
自带变量: CC CPPFLAGS CFLAGS LDFLAGS
自动变量: $@ $< $^
模式规则:
%.o:%.c------> 前后的%必须是相同
- 例子:
target=main
object=main.o fun1.o fun2.o sum.o
CC=gcc
CPPFLAGS=-I./
$(target):$(object)
$(CC) -o $@ $^
%.o:%.c
$(CC) -o $@ -c $< $(CPPFLAGS)
#main.o:main.c
# gcc -o main.o -c main.c -I./
#
#fun1.o:fun1.c
# gcc -o fun1.o -c fun1.c
#
#fun2.o:fun2.c
# gcc -o fun2.o -c fun2.c
#
#sum.o:sum.c
# gcc -o sum.o -c sum.c
第四个版本:
1.wildcard – 查找指定目录下的指定类型的文件
src=$(wildcard *.c) //找到当前目录下所有后缀为.c的文件,赋值给src
2.patsubst – 匹配替换
obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o
如: 当前目录下有a.c b.c c.c
src=$(wildcard *.c) -----> src=a.c b.c c.c
obj=$(patsubst %.c,%.o, $(src)) -----> obj=a.o b.o c.o
- 例子
src=$(wildcard ./*.c)
object=$(patsubst %.c, %.o, $(src)) # 将.c文件替换成.o文件
# object=main.o fun1.o fun2.o sum.o
target=main
CC=gcc
CPPFLAGS=-I./
$(target):$(object)
$(CC) -o $@ $^
%.o:%.c
$(CC) -o $@ -c $< $(CPPFLAGS)
#main.o:main.c
# gcc -o main.o -c main.c -I./
#
#fun1.o:fun1.c
# gcc -o fun1.o -c fun1.c
#
#fun2.o:fun2.c
# gcc -o fun2.o -c fun2.c
#
#sum.o:sum.c
# gcc -o sum.o -c sum.c
第五个版本:
增加清理功能.
终极目标: makefile文件中第一次出现的目标叫做终极目标
.PHONY:clean
clean:
rm -f ....
使用-f可以指定makefile文件, 如: make -f mainmak
总结:
如果不需要取别名
可以先make clean
然后make生成可执行文件
- 例子
src=$(wildcard ./*.c)
object=$(patsubst %.c, %.o, $(src))
# object=main.o fun1.o fun2.o sum.o
target=main
CC=gcc
CPPFLAGS=-I./
$(target):$(object)
$(CC) -o $@ $^
%.o:%.c
$(CC) -o $@ -c $< $(CPPFLAGS)
.PHONY:clean
clean:
-rm -f $(target) $(object)
#main.o:main.c
# gcc -o main.o -c main.c -I./
#
#fun1.o:fun1.c
# gcc -o fun1.o -c fun1.c
#
#fun2.o:fun2.c
# gcc -o fun2.o -c fun2.c
#
#sum.o:sum.c
# gcc -o sum.o -c sum.c
07makefile文件的更多相关文章
- Mapreduce的文件和hbase共同输入
Mapreduce的文件和hbase共同输入 package duogemap; import java.io.IOException; import org.apache.hadoop.co ...
- mapreduce多文件输出的两方法
mapreduce多文件输出的两方法 package duogemap; import java.io.IOException; import org.apache.hadoop.conf ...
- 01.SQLServer性能优化之----强大的文件组----分盘存储
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...
- SQL Server 大数据搬迁之文件组备份还原实战
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搬迁步骤(Procedure) 搬迁脚本(SQL Codes) ...
- SQLSERVER将一个文件组的数据移动到另一个文件组
SQLSERVER将一个文件组的数据移动到另一个文件组 有经验的大侠可以直接忽视这篇文章~ 这个问题有经验的人都知道怎麽做,因为我们公司的数据量不大没有这个需求,也不知道怎麽做实验 今天求助了QQ群里 ...
- SQL Server中的高可用性(2)----文件与文件组
在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性.在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性.SQL Server允许在某些文件损坏或离线的情况下,允 ...
- C# ini文件操作【源码下载】
介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
随机推荐
- 接口combine
需求描述 进行复杂项目开发时,服务端(数据接口实现端)会把接口拆分的比较细粒度,以方便在更多地方复用.而拆分后的接口在前端进行组合请求时,通常会出现一个区块要请求5.6个接口甚至更多接口请求才能拿到想 ...
- 设计模式-观察者模式Observe的实现
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> / ...
- java中finally块儿是怎么工作的?有什么意义?
10.finally块 马克-to-win:finally块儿是怎么工作的?有什么意义?finally关键字创建一个代码块.没有try,finally块儿不能单独存在.该代码块在一个try/catch ...
- jsp基础、el技术、jstl标签、javaEE的开发模式
一.jsp技术基础 1.jsp脚本和注释 jsp脚本: 1)<%java代码%> ----- 内部的java代码翻译到service方法的内部 2)<%=java变量或表达式> ...
- Python入门-初识变量类型
上一篇我们学习了第一行代码,我们print()了很多代码,我们可以print哪些东西呢,这一篇来讲. print()括号里面可以放哪些东西呢?..可以放很多东西,只要是Python的全部数据类型都可以 ...
- Spring-AOP动态代理技术(底层代码)
1.JDK代理:基于接口的动态代理技术 目标对象必须有接口,目标对象有什么方法,目标接口就有什么方法, 运行期间基于接口动态生成代理对象,所以代理对象也就有目标对象同样的方法. 注意:以下代码只是底层 ...
- 查看k8s的yaml里面反馈的错误,不仅仅是通过日志来查看错误
使用:kubectl describe pod......例如: kubectl describe pod api-55f5d8d49d-kzmcj ///////////////////////// ...
- 『现学现忘』Git基础 — 1、版本控制系统介绍
在具体了解Git之前,首先需要我们了解一下VCS,即版本控制系统(version control system) 1.什么是版本控制系统 版本控制是一种记录一个或若干个文件内容变化,以便将来查阅特定版 ...
- Java学习day40
跟着视频回顾了整个JavaSE的学习过程
- canvas基础简单易懂教程(完结,多图)
目录 Canvas学习 一. Canvas概述 1.1 Hello world 1.2 Canvas的像素化 1.3 Canvas的动画思想 1.4 面向对象思维实现canvas动画 二.Canvas ...