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.linuxmake -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的工作方式:工作时候执行步骤如下
- 读入Makefile文件;
- 读入Makefile的include文件;
- 读入变量并初始化;
- 读入隐晦规则文件,并且展开;
- 为目标文件创建依赖关系;
- 根据依赖关系看哪些需要更行;
- 执行生成命令;
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 > bigoutputlittleoutput : text.g generate text.g -little > littleoutput-$(sunst output,,$@)中的$表示一个函数的引用
Makefile====>静态模式
: : ...target是一系列目标文件,可以有通配符target-pattern指明targets的模式,目标集合的模式prereq-patterns指明目标的依赖模式一个例子:object = foo.o bar.oall:$(object)$(object):%.o:%.c $(CC) -c $(CFLAGS) $< -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 $<