Makefile的编写
编写Makefile编译一个大型项目所必须的,在使用Makefile之前首先需要对gcc有所掌握。
C 和 C++ 编译器:
gcc 是GNU C Compiler 的缩写,经过十来年发展,意义变成了 GNU Compiler Collection,可
同时支持 C、 C++、 Objective C 和 Java 等.
编译 C++程序,我们可以直接用 GCC 编译其中的 g ++命令,用法同 gcc;当然 g++ 和 gcc
都可以用来编译 c 和 c++程序。 gcc 编译 c++程序需要带上 -lstdc++ 指定使用 c++库。
gcc编译常用选项:
注意: -c 选项在编写大型程序是必须的,多个文件的源代码首先需要编译成目标代码,再
链接成执行文件。如果由多个源文件,工程做法建议采用 makefile
关于gcc的编译优化选项:
代码其实可以执行更快更高效? 代码质量 + 编译选项优化
最简单有效的方式,使用 -Onum 选项. gcc 提供了三个级别的优化选项: O1 O2 O3,理论上
-O3 选项可以生成执行效率最高的代码,但以为着更大的风险。通常, -O1 -O2 选项就可以
满足绝大多数的优化要求。如, Nginx 编译就采用-O1
/*----------------步入正题-Makefile的编写-------------*/
程序的编译和链接:
使用 C、 C++编写可执行程序,首先要把源文件编译成中间代码文件, Linux 下是 .o 件,即 Object File,
这个动作叫做编译(compile)。然后再把大量的 Object File 合成执文件,这个动作叫作链接(link)。
一个项目,拥有成百上千的源程序文件,编译链接这些源文件都是由规则的, Makefile
闪亮登场! Makefile 确定整个工程的编译规则,只需要一个 make 命令,就可以实现“自动化
编译”。 make 是一个解释 makefile 中指令的命令工具,一般来说,大多数的 IDE 都有这个
命令,比如: Delphi 的 make, Visual C++的 nmake, Linux 下 GNU 的 make。
make的工作原理:
通常在一个项目里,我们的规则是:
1)如果这个工程没有编译过,那么我们的所有 C 文件都要编译并被链接。
2)如果这个工程的某几个 C 文件被修改,那么我们只编译被修改的 C 文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的 C 文件,并链接目标程序。
只要我们的 Makefile 写得够好,我们只用一个 make 命令就可以完成, make 命令会自动智
能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和
链接目标程序。
Makefile 的规则:
target 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签
(Label),对于标签这种特性, 暂不叙述。
prerequisites 就是,要生成那个 target 所需要的文件或是目标。
command 也就是 make 需要执行的命令。(任意的 Shell 命令)
这是一个文件的依赖关系,也就是说, target 这一个或多个的目标文件依赖于 prerequisites
中的文件,其生成规则定义在 command 中。说白一点就是说, prerequisites 中如果有一个以
上的文件比 target 文件要新的话, command 所定义的命令就会被执行。这就是 Makefile 的
规则。也就是 Makefile 中最核心的内容。
一个范例:
make的工作流程:
1、make 会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中, 他会找到
“hello_demo”这个文件,并把这个文件作为最终的目标文件。
3、如果 hello_demo 文件不存在,或是 hello_demo 所依赖的后面的 .o 文件的文件修改时间
要比 hello_demo 这个文件新,那么,他就会执行后面所定义的命令来生成 hello_demo 这个
文件。
4、如果 hello_demo 所依赖的.o 文件也不存在,那么 make 会在当前文件中找目标为.o 文件
的依赖项,如果找到则再根据那一个规则生成.o 文件。(像不像堆栈过程? )
5、当然, 我们的 C 文件和 H 文件都存在,于是 make 会生成 .o 文件,然后再用 .o 文件
生命 make 的终极任务,也就是执行文件 hello_demo 了。
/*------------------------Makefile进阶----------------------*/
Make变量:
一个 Makefile 里我们发现经常会由重复的内容, 如上面范例中的前两行中的
hellospeak.o speak.o
如果我们 的工 程需 要加 入 一个新 的[.o]文 件, 那么 我们我 们好 几个 地方 都需 要修改 原来的
makefile。当然,我们的 makefile 并不复杂,所以在两个地方加也不累,但如果 makefile 变得复
杂,那么我们就有可能会忘掉一个需要加入的地方,而导致编译失败。所以,为了 makefile 的易维
护,在 makefile 中我们可以使用变量。 makefile 的变量也就是一个字符串, 完全可以理解成 C 语
言中的宏 .
变量定义: 变量名 = 值 ##使用 shell script 的语法
如:
objects = hellospeak.o speak.o
我们上面的 makefile 就可以变成:
更省事的方式,让 Make 自动推导
make 很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]
文件后都写上类似的命令,因为,我们的 make 会自动识别,并自己推导命令。
只要 make 看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果 make 找到一个
hello.o,那么 hello.c,就会是 hello.o 的依赖文件。并且 gcc -c hello.c 也会被推导出来,于是,
我们的 makefile 再也不用写得这么复杂。我们的是新的 makefile 又出炉了。