Makefile ===> Makefile 快速学习

Makefile =====> 首先明确的

  • Makefile 关系到整个工程的编译规则,一个工程中源文件不计其数,按类型功能模块分别放在不同目录中,makefile 指定一些特殊规则来编译文件,哪些文件先编译,哪些后编译,哪些需要重新编译,像一个脚本一样,也可以执行操作系统的命令。
  • Makefile 带来的好处就是自动化编译。
  • 程序的编译和链接:源文件编译成中间文件(.o .obj等) 叫做编译,中间文件合成执行文件,叫做链接。
  • 编译:此时需要语法正确,函数与变量的声明正确
  • 链接:主要是链接函数和全局变量,只管函数的中间目标文件,链接的时候需要明显的指定出中间文件的名字,但是又很多,对于编译不方便。所以我们给中间目标文件打包(windows下 库文件library.lib文件 Unix下是.a文件)
  • 总结:源文件===>中间目标文件===>可执行文件,在编译的时候如果函数未被生命,会给警告,但是可以生成object file。但是在链接的时候在所有的objectfile中寻找函数的实现,找不到就报错。

Makefile ======> 简单的介绍

编译链接的规则:

  • 如果这个工程没有编译过,那么我们的所有的C文件都要编译并被链接。
  • 如果这个工程中的几个c文件修改,那么我们只编译修改过的C文件,并链接目标程序。
  • 如果工程的头文件被改变了,我们需要编译引用这几个头文件的C文件,并链接目标程序。
粗略的规则
taget .. : prerequisites ... command ... ...
  • target 既可以有是objectfile,也可以是可执行文件。还可以是一个标签。
  • 要生成target素排序要的文件或者目标,prerequistites。
  • command make需要执行的命令。
  • makefile 的最核心内容:如果prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。

Makefile ===> 总述

Makefile主要包含五个东西,显示规则,隐晦规则,文件指示,变量定义和注释。

  • 显示规则:要写makefile明显的指出,生成的文件,文件的依赖文件,需要的命令;
  • 隐晦规则:make自动推导的功能,比较粗略的书写makefile;
  • 变量定义:类似c语言的宏定义,一般都是字符串,变量在makefile执行的时候扩展到相应位置;
  • 文件指示:包括三个部分,一个makefile中引用另外一个makefile,二个是根据某些情况指定有效的部分,像c语言中的#if一样;还有就是定义多行的命令;
  • 注释:用#注释
  • makefile中的命令行以tab开始

Makefile的文件名:

Makefile 或者 makefile 或者 GNUmakefile 或者别名 Makefile.linux

make -f Makefile.linux 或者
make --file Makefile.linux

Makefile引用其他makefile:

#include foo.make *.mk $(bar)

inlclude没有指定路径的话,在当前目录下寻找,如果没有找到,make还会在以下几个目录中寻找:

  • make执行的时候,如果有“-I"和”--include-dir“的参数,那么make就会在这个参数指定的目录下去寻找;
  • 如果目录<prefix>/include 存在的话,make也会寻找;
  • -include <filename> 表示include过程中不管出现什么错误,都不要报错继续执行;

环境变量MAKEFILES 有时候Makefile除了怪事的话,可以看看是不是定义了这个变量。

make的工作方式:工作时候执行步骤如下

  1. 读入Makefile文件;
  2. 读入Makefile的include文件;
  3. 读入变量并初始化;
  4. 读入隐晦规则文件,并且展开;
  5. 为目标文件创建依赖关系;
  6. 根据依赖关系看哪些需要更行;
  7. 执行生成命令;

1-5步为第一个阶段,6-7为第二个阶段。第一个阶段中,如果定义的变量被使用了,那么,make会把其展开在使用的位置。但make并不会完全马上展开,make使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。

当然,这个工作方式不一定要清楚,但是知道这个方式也会对make更为熟悉。

Makefile====>多目标

  • Makefile中的规则的目标可以不止一个,有时候我们多个目标依赖与一个文件,并且命令大体相同,就可以合并起来。
  • 可以使用自动化变量"$@",这个变量表示目前规则中所有的目标的集合。例子如下:
bigoutput littleoutput : text.g
    generate text.g -$(subst output,,$@) > $@

上述规则等价于:
bigoutput : text.g
    generate text.g -big > bigoutput
littleoutput : text.g
    generate text.g -little > littleoutput

-$(sunst output,,$@)中的$表示一个函数的引用

Makefile====>静态模式

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

target是一系列目标文件,可以有通配符
target-pattern指明targets的模式,目标集合的模式
prereq-patterns指明目标的依赖模式

一个例子:

object = foo.o bar.o
all:$(object)
$(object):%.o:%.c
    $(CC) -c $(CFLAGS) $< -o $@

$<表示依赖的目标集合,$@表示目标集合。
上边的展开就是:
foo.o : foo.c
    $(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
    $(CC) -c $(CFLAGS) bar.c -o bar.o

如果,我们的"%.o"有几百个,我们的这种很简单的“静态模式”可以完成一堆规则。

files = fz.elc bar.o foo.o
$(filter %.o,$(files)):%.o:%c
    $(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc, $(files)):%.elc:%.el
    emacs -f batch-byte-compile $<

 

 

 

posted @ 2012-09-13 15:47  事件轮询,回不到过去  阅读(441)  评论(0编辑  收藏  举报