下面的内容是直接从个人ipython notebook中摘录出来的因此可能不是很清楚,若是想查看完整版本以及例子,能够访问:html
git地址: git@github.com:liangz0707/WTF-makefile.gitpython
下载地址:https://github.com/liangz0707/WTF-makefile/archive/master.zipios
若是不能查看ipython notebook 能够直接打开其中的lession.html 结果是同样的 git
What is Compiler?程序员
Compiler=编译器,就是将某种代码编译成机器语言,或者说编译成可以由处理器直接执行的“代码”。一个程序员会以一种语言在编辑器当中编写语句。例如:c、Lisp。编写完成后生成的文件就是源代码。而后程序员运行具体的编译器,把上述文件名做为参数进行编译。github
执行过程当中,编译器会依照语法顺序,逐一对语句进行解析。最终生成输出代码。通常的编译器的输出结果叫作object code或者object module(这里的object和面向对象中的object不一样)。这里的object code是机器语言。安全
在传统的操做系统当中,在编译以后每每还须要额外的步骤,由于当有多于一个Object Code时 他们的指令、和数据之间存在关系,因此须要进行连接,获得的结果是。 load module。less
GCC是c语言的编译器之一:编辑器
gcc is the "GNU" C Compiler, and g++ is the "GNU C++ compiler工具
咱们编写一个hello.c文件(见目录):
/#include "iostream.h"
int main()
{
cout << "Hello\n";
}
执行以下命令,输出的结果就是可执行的机器码(.exe可执行程序),默认文件名是a.exe
主要g++编译的源文件中头文件的引用通常为#include< iostream>,而不是#include< iostream.h>,而且要注意使用命名空间。
!g++ hello.c -o hello
在实际的编译过程当中,逐个的编译源代码过于冗杂,尤为是当你须要包含不少源文件时,你不得不每一次都要打字输入。
而是用Makefile就是为了简化不少源文件的编译过程。 例如咱们有不少c问见须要编译:
main.cpp
hello.cpp
factorial.cpp
functions.h 以上的文件都是经过头文件串联起来的
#若是须要手动的编译,以下很是麻烦
!g++ main.cpp hello.cpp factorial.cpp -o hello
#执行上面获得的文件
!hello
把source code转换成object files
将不一样的object files链接成可执行的机器码(.exe) 下面使用最简单的Makefile 来进行编译,代替手工过程
基本的Makefile组成以下:
target: dependencies
[tab]system command
‘target’能够理解为要编译的目标或任务(分号后的内容),dependencies表示要完成这个目标所须要的前提。编写成咱们须要的格式以下:
all:
g++ main.cpp hello.cpp factorial.cpp -o hello
从makefile文件中能够看出咱们的目的是‘all’,这是makefiles默认的目标。make工具在没有特殊声明的时候会有限执行‘all’,咱们看到all是没有依赖的,因此能够安全的执行。
有时候咱们会使用不一样的‘target’。由于当咱们修改了一个文件的时候,不但愿把全部的文件都进行从新编译。
例如如下的例子:
all: hello
hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello main.o: main.cpp
g++ -c main.cpp factorial.o: factorial.cpp
g++ -c factorial.cpp hello.o: hello.cpp
g++ -c hello.cpp
clean:
del *o hello.exe
至关于把编译的过程(上述的两部,编译、链接)拆分开。
咱们看到all只有一个依赖,而没有命令,这是为了让make可以正确的执行。all必须执行才能完成。
对于每个可用的目标全部的依赖都会被搜索,若是找到则执行。
咱们还看到了一个clean的目标,他能够快速的清楚全部的object和可执行程序,至于如何使用稍后解释。
例子以下:
# I am a comment, and I want to say that the variable CC will be
# the compiler to use. CC=g++
# Hey!, I am comment number 2. I want to say that CFLAGS will be the
# options I'll pass to the compiler.
CFLAGS=-c -Wall
all: hello
hello: main.o factorial.o hello.o
$(CC) main.o factorial.o hello.o -o hello
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
factorial.o: factorial.cpp
$(CC) $(CFLAGS) factorial.cpp
hello.o: hello.cpp
$(CC) $(CFLAGS) hello.cpp
clean:
del *o hello.exe
如上所示,使用$(VAR)就能够轻松的访问变量。