跟我一起学Makefile

Makefile介绍:

      make命令属于gnu工具(gcc,g++,gdb,make,cvs,patch,diff,binutils等),make命令会在当前目录下按顺序查找文件“Makefile”、“makefile”、“GNUmakefile”,也可以使用其他的名字来书写Makefile,需要再make后面使用 “-f”、“-file”参数来指定文件名,如:make -f Make.Linux;每条规则中的命令和操作系统 Shell的命令行是一致的。make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非 命令是紧跟在依赖规则后面的分号后的。在命令行之间中的空格或是空行会被忽略,但是如果该空格或空行是以Tab键开头的,那么make会认为其是一个空命令。

GNU的make工作时的执行步骤入下:(想来其它的make也是类似)
1)、读入所有的Makefile。
2)、读入被include的其它Makefile。
3)、初始化文件中的变量。
4)、推导隐晦规则,并分析所有规则。
5)、为所有的目标文件创建依赖关系链。
6)、根据依赖关系,决定哪些目标要重新生成。
7)、执行生成命令。

一、自动化变量:

$^:代表所有依赖的文件

$@:代表目标

$<:代表第一个依赖的文件

       大多说的c/c++编译器都支持一个”-M“的选项,即自动寻找文件中依赖的头文件,如果使用的是GNU的c/c++编译器,需要使用”-MM“参数,否则”-M“会将

标准库的头文件包含进来



二、静态模式与多目标

<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>

targets定义了一系列的目标文件,可以有通配符。是目标的一个集合。
target-parrtern是指明了targets的模式,也就是的目标集模式。
prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目标的定义。


例1:展开:

obj = foo.o bar.o foo.o:foo.c

all: $(obj) $(CC) -c $(CFLAGS) foo.c -o foo.o

$(obj): %.o : %.c => bar.o: bar.c

$(CC) -c $(CFLAGS) $< -o $@ $(CC) -c $(CFLAGS) bar.c -o bar.o

注:上面的例子中,指明了我们的目标从$object中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量

$object集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo bar”,并为其加下“.c”的后缀,于是,我们的依赖目标

就是“foo.c bar.c”。

例2:

files = foo.elc bar.o lose.o

$(filter %.o,$(files)): %.o :%.c

$(CC) -c $(CFLAGS) $< -o $@

$(filter %.elc,$(files)): %.elc:%.el

emacs -f batch-byte-compile

注:$(filter %.o,$(files))表示调用Makefile函数,过滤”$filter“集合,只要其中模式为"%.o"的内容

三、 清空目标文件的规则:

每个Makefile中都应该有一个清空目标文件(.o)的规则,这不仅便于重新编译,也很利于保持文件的清洁;

1、clean:

       rm  edit $(obj)

2、更为稳健的方式

      .PHONY: clean

clean:

-rm edit $(obj)

      .PHONY表示clean是一个“伪目标”在行前面加上 “-”表示即使出问题,略过,仍要继续后面的操作。clean 最好放在Makefile的最后。”make 

clean" 将清除所有被清除的文件。”cleanobj“ 和 ”cleandiff“这两个伪目标有点像子程序。可以通过输入”make cleanall“和 ”make cleanobj“以

及”makediff“来达到清除不同类文件的目的 

三、引用其他Makefile

  1)include <filename>    #filename  可以是当前操作系统Shell的文件模式(可以保含路径和通配符)

 如: include foo.mk

    注:在include前面可以有一些空字符,但是绝不能是[Tab]键开始。

三、在规则中引用通配符

  和shell相同make支持“*”,“?”,“[...]”三个通配符。

  obj = *.o    #表示obj的值为"*.o",并不是所有的 .o文件,如果想代表所有的.o文件则 obj = $(wildcard *.o)

  注:在Makefile中的命令,必须要以[Tab]键开始,Makefile第一次编译的错误不会为致命错误,会在整个

Makefile编译结束,再次重新编译错误位置,如果还未通过则生成致命错误

4、shell函数 (:来自 《跟我一起写Makefile》)

     shell函数与其他函数不同,它的参数应该就是linux命令。shell函数把执行操作系统命令后的输出作为函数返回值。如:

   contents:=$(shell cat foo)     或者  files:=$(shell echo *.c)

   注意,这个函数会生成一个shell程序执行命令,所以你要注意其运行性能,如果在Makefile中有比较复杂的规则,并且大量使用该函数,那么对于你的系统性能是有害的

特别的是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想象的多得多。

Makefile 在 Unix 上写程式的人大概都碰过 Makefile,尤其是用 C 来开发程式的 人。用 make 来开发和编译程式的确很方便,可是要写出一个 Makefile 就不简单了。偏偏介绍 Makefile 的文件不多,GNU Make 那份印出来要几 百页的文件,光看完 Overview 就快阵亡了,难怪许多人闻 Unix 色变。 本文将介绍如何利用 GNU Autoconf 及 Automake 这两套软体来协助我们 『自动』产生 Makefile 档,并且让开发出来的软体可以像 Apache, MySQL 和常见的 GNU 软体一样,只要会 ``./configure'', ``make'', ``make install'' 就可以把程式安装到系统中。如果您有心开发 Open Source 的软体,或只是想在 Unix 系统下写写程式。希望这份介绍文件能 帮助您轻松地进入 Unix Programming 的殿堂。 1. 简介 Makefile 基本上就是『目标』(target), 『关连』(dependencies) 和 『动作』三者所组成的一连串规则。而 make 就会根据 Makefile 的规则 来决定如何编译 (compile) 和连结 (link) 程式。实际上,make 可做的 不只是编译和连结程式,例如 FreeBSD 的 port collection 中, Makefile 还可以做到自动下载原始程式套件,解压缩 (extract) ,修补 (patch),设定,然後编译,安装至系统中。 Makefile 基本构造虽然简单,但是妥善运用这些规则就也可以变出许多不 同的花招。却也因此,许多刚开始习写 Makefile 时会感到没有规范可 循,每个人写出来的 Makefile 长得都不太一样,不知道从何下手,而且 常常会受限於自己的开发环境,只要环境变数不同或路径改一下,可能 Makefile 就得跟着修改。虽然有 GNU Makefile Conventions (GNU Makefile 惯例) 订出一些使用 GNU 程式设计时撰写 Makefile 的一些标 准和规范,但是内容很长而且很复杂, 并且经常做些调整,为了减轻程式 设计师维护 Makefile 的负担,因此有了 Automake。 程式设计师只需写一些预先定义好的巨集 (macro),交给 Automake 处理 後会产生一个可供 Autoconf 使用的 Makefile.in 档。再配合利用 Autoconf 产生的自动设定档 configure 即可产生一份符合 GNU Makefile 惯例的 Makeifle 了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值