makefie文件的基本说明和使用

1. Makefile的三要素(构成一个规则):

目标:依赖 //目标在前,依赖在后,分号分开

命令 //命令前面一个tab缩进

2. 举例说明:

cal:add.c sub.c #直接依赖.c文件

gcc -c add.c sub.c -o cal

3. 举例说明拆分演进

cal:add.o sub.o #改为依赖.o文件

gcc add.o sub.o -o cal

add.o:add.c #.o文件依赖.c文件

gcc -c add.c #gcc -c生成add.o文件

sub.o:sub.c #.o文件依赖.c文件

gcc -c sub.c #gcc -c生成sub.o文件

4. 总结

最终目标写在第一条,比如上面的拆分演进里,目标cal写在第一条,最终目标依赖的东西如果存在,则直接执行,如果不存在,再往下查找依赖,以此类推。

从上往下查找依赖,以此类推,树状结构。

从下往上执行命令,最终生成第一条的终极目标。

附:是否重新执行命令(编译),是比较各个目标和自身依赖的时间来确定的(包括最终目标和各个子目标)。正常情况目标是要比依赖晚的,因为目标是由依赖生成的嘛,如果依赖修改了,那依赖的时间就比目标的晚了,那就要重新编译了。

5. 使用Makefile的变量

obj=add.o sub.o #自定义变量

target=cal #自定义变量

$(target):$(obj) #这里的$(自定义变量) 表示引用自定义变量

gcc $(obj) -o $(target)

%.o:%.c #模式匹配使用%,比如$(obj)匹配后变为add.o:add.c,sub.o:sub.c

gcc -c $< -o [email protected] #变量$<表示规则里的第一个依赖(比如add.o:add.c规则里的第一个依赖就是add.c,当然这个规则本身就只有一个依赖),[email protected]表示规则里的目标

6. 使用Makefile的变量

obj=add.o sub.o

target=cal

$(target):$(obj)

$(CC) $^ -o [email protected] #变量CC是Makefile的预定义变量,默认值是cc,也就是gcc, $^表示规则里的所有依赖

%.o:%.c

$(CC) -c $< -o [email protected] #变量$<,[email protected],$^称为自动变量,只能在规则里的命令里面使用

7. Makefile的函数使用

src=$(wildcard ./*.c) #wildcard是函数名,./*.c是函数参数,这里表示当前目录下的所有.c文件,多个参数之间使用逗号分开,$表示取值;整体就是查找当前目录下的所有.c文件

obj=$(patsubst ./%.c, ./%.o, $(src)) //字符串替换,替换名称.c为.o,%是通配符

target=cal

$(target):$(obj)

$(CC) $^ -o [email protected]

%.o:%.c

$(CC) -c $< -o [email protected]

其他函数:$(subst FROM,TO,TEXT),$(patsubst PATTERN,REPLACEMENT,TEXT),$(strip STRINT),$(findstring FIND,IN)等等,更多可参考GNU make手册

8.make clean

.PHONY:clean #声明虚伪目标,这样就不会比较目标时间了,防止当前目录下刚好有一个clean文件,误当作目标拿来比较,从而提示你clean是最新的,而不执行clean操作

clean: #没有依赖的情况

rm -f $(obj) $(target) #删除当前目录下的.o文件和cal文件

执行:make clean #执行时指定clean目标,clean目标和cal目标是没有任何关系的

附:直接执行make,是执行第一个目标;make [目标],是执行指定的目标。

9. -命令 #加上-,表示如果命令有误,就忽略它继续执行下去,如果不加-,一旦命令有误就立刻终止执行了。

举例说明:-rm /test 删除根目录下的test文件需要root权限,所以报错,但是加了-,会继续执行其他命令而不会终止。

10.更多参考GNU make手册

时间: 2024-10-26 20:57:11

makefie文件的基本说明和使用的相关文章

【转】Android源代码编译命令m/mm/mmm/make分析--不错

原文网址:http://blog.csdn.net/luoshengyang/article/details/19023609 在前文中,我们分析了Android编译环境的初始化过程.Android编译环境初始化完成后,我们就可以用m/mm/mmm/make命令编译源代码了.当然,这要求每一个模块都有一个Android.mk文件.Android.mk实际上是一个Makefile脚本,用来描述模块编译信息.Android编译系统通过整合Android.mk文件完成编译过程.本文就对Android源

QT程序制作deb包并安装在应用程序菜单

制作原理:打包:将QT制作的源程序(没有编译的)用debian压缩打包(这里是用脚本对源程序再编译)安装:将deb包中的源程序解压(默认解压到根目录)到规定系统文件中并编译(postinst脚本)卸载:将解压的所有文件删除(postrm脚本)例子:1.新建deb包文件myded|——mydeb     |————application           |——addressbook(此目录存放QT的源程序和configure脚本)           |————lib             

GNU Autotools的研究(转)

最近对Linux下软件项目的构建过程研究了一番.Linux下的软件项目通常用Autotools工具集和make工具来构建,我们通常使用./configure.make.make install这样的命令来编译安装软件包,则这样的项目一般就是使用Autotools工具集来构建,再加上GNU make工具来编译安装.   使用Autotools的目的:  (1)构建可移植的软件包.在不同操作系统上(主要是不同的类Unix系统),可能同样功能函数名称的不同,同样功能的库的名字的不同,以及头文件的不同,

CentOS下的编译源代码安装软件( 以安装python3为例 )

在 CentOS 下安装软件,可以使用 rpm软件包.yum工具.自行下载源代码进行编译安装,其中编译安装的定制性较高 对于一些在软件,自行下载源代码进行编译安装较为方便 程序:源代码 --> 编译 --> 链接 --> 运行 执行编译安装步骤: 获取源代码并解压 #tar xf xxx.tar.gz //或者: #tar xf xxx.tar.bz2 在解压完的源代码目录下执行 configure 脚本 #./configure [options] 选项: --help 查看该脚本帮助

JNI调用so动态库

1.编写native接口 package org.demo; public class JniDemo { public static native int bmp2fea(byte[] bmp, byte[] fea, byte[] err); public static native int feaMatch(byte[] fea1, byte[] fea2, int level); } 2.根据native接口生成声明文件(.h) javah -classpath . -jni org.d

openwrt luci web分析

openwrt luci web分析 来源 https://www.jianshu.com/p/596485f95cf2 www/cbi-bin/luci #!/usr/bin/lua --cgi的执行命令的路径 require"luci.cacheloader" --导入cacheloader包 require"luci.sgi.cgi" --导入sgi.cgi包 luci.dispatcher.indexcache = "/tmp/luci-index

最佳vim技巧

最佳vim技巧----------------------------------------# 信息来源----------------------------------------www.vim.org         : 官方站点comp.editors        : 新闻组http://www.newriders.com/books/opl/ebooks/0735710015.html : Vim书籍http://vimdoc.sourceforge.net/cgi-bin/vim

GNU-makefle (三) 规则语法、文件查找、伪目标

参考链接:http://blog.csdn.net/haoel/article/details/2889 当命令和依赖关系描述在同一行时,可以使用分号 分隔. 当命令太长时,也可以用反斜杠 \ 来分隔成多行,分隔出的行首有没有tab都可以(空格更无所谓了). 在指定文件目录时,可以用~来表示系统home目录,因为make会以shell来执行. VPATH Makefile文件中的特殊变量.它指定make可以去哪些目录找寻依赖文件和目标文件. 默认不定义它,则在当前目录找,多目录用冒号(:)分隔

Mac下获取AppStore安装包文件路径

本文介绍了Mac下如何找到AppStore下载的安装包路径,以及如何提取出来供以后使用的相关步骤,希望对大家有所帮助. 通过远在大洋彼岸的苹果服务器下载东西,确实有够慢啊!AppStore更甚:甚至都经常提示连不上服务器,而有些软件呢,还必须从AppStore下载安装,所以没办法,谁让上了苹果的贼船呢!公司的网速更是不敢恭维,以至于基本上不下东西,除非像这次一样:手贱的把iPhone6升级到8.2.2了,然后Xcode6.1.1真机调试不成了,所以需要下个Xcode6.2.昨天刚更新的Xcode