_010_makefile
Posted huangtiandi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了_010_makefile相关的知识,希望对你有一定的参考价值。
=================================
makefile 是项目的管理工具,管理源代码用的,这是我们自己创建的,不是第三方工具
所以我们们直接创建一个文件夹就叫Makefile,文件里面有一个makefile的文件以及源代码
Makefile规则
目标,依赖,命令
目标: 依赖条件 这是第一行内容
命令 这是第二个行,目标和命令必须要缩进
1 app:main.c add.c2 2 gcc main.c add.c -o app
然后直接make,就会调用本目录下的makefile文件
有一种情况,那就是修改某一个.c文件,再次编译的时候,难道还要再调用一次上面的规则吗,如果很多.c
每次修改都编译全部,明显效率很低
所以可以写成如下的规则
1 app:main.o add.o 2 gcc main.o add.o -o app 3 4 main.o:main.c 5 gcc -c main.c 6 7 add.o:add.c 8 gcc -c add.c
这样,app是终极目标,make之后,去读取第一行,首先依赖,因为我们没有main.o(还没编译),所以会去找下面的规则
main.o:main.c 所以就先执行这个命令,然后依次这样下次gcc main.o add.o -o app这条命令是生成可执行文件的命令
这样的话make便会一个一个来编译,这样make会自动判断文件是否修改了,如果修改了才会再次进行编译
当然上面这些只是初级的修改,我们发现有很多代码是重复的,只要修改一小部分就可以再用,所以可以使用变量和模式来解决
使用变量
1 obj=main.o add.o 2 target=app 3 app:$(obj) 4 gcc $(target) -o app 5 6 main.o:main.c 7 gcc -c main.c 8 9 add.o:add.c 10 gcc -c add.c
当然上面还没有修改完,因为如果我们有不止一个.c文件,还有sub.c mul.c那么我们需要写一样的规则,只不过名字变了
很明显这是非常不效率的,所以我们应该这样修改
obj=main.o add.o target=app app:$(obj) gcc $(target) -o app %.o:%.c gcc -c $< -o [email protected]
要理解上面的这个,就需要知道makefile中自动匹配和自动变量的概念
匹配:首先make找依赖,没找到main.o,然后去找下一个规则,下一个规则是一个%.o,这个%代表着匹配,所以make就去
把上面的main.o给匹配过来,同理,%.c也是这样匹配的,然后指定命令,然后又会到下一个依赖,周如复始
那么命令执行就需要理解自动变量的概念 $< 代表规则中的第一个依赖 [email protected]规则中的第一个目标 $^规则中的所有依赖
make中还有一些默认的变量 CPPLAGS预编译器需要的选项如 -I(大写i) CFLAGS编译的时候使用的参数 -Wall -g
链接库使用的选项 -L -l(小写L)
makefile中的函数
makefile中的函数都有返回值,且必须拿到其返回值,下面便是makefile的终极版本
obj=main.o add.o target=app src=$(wildcard ./*.c) ojb=$(patsubst ./%.c, ./%.o, $(src)) #注意这里是% app:$(obj) gcc $(target) -o app %.o:%.c gcc -c $< -o [email protected] .PHONY:clearn clearn: -mkdir /aa rm -f $(obj) $(target)
wildcard(匹配)函数是匹配文件用的,返回所有匹配到名称
patsubst(替换),第一个参数是要替换的,第二个参数是需要替换成什么,第三参数是源,也就是wildcard返回的那些名称
额外的规则,使用的时候直接make 目标 这样就会调用指定的目标
但是有一个问题,那就是如果目标的名字和本目录下的文件重名,那么make检查是否修改的时候会去检测
已经生成的规则是否改变,我们的目标还没生成出来,而那个文件我们不去修改
所以永远都检测到是最新的,所以make 目标的时候就出问题了
要在额外的目标的前面加个 .PHONY:目标 表示这是一个尾目标,就不再去检测是否修改
如果我们写的命令不确定能不能指定,或者说只是一条额外的命令,那我们就可以在命令的前面加一个-
这样即使这个命令出错,也会直接忽略,然后继续下一条命令
以上是关于_010_makefile的主要内容,如果未能解决你的问题,请参考以下文章
ANDROID_MARS学习笔记_S01原始版_010_ContentProvider
Java千百问_01基本概念(010)_Solaris操作系统是什么