对于一个简单的程序。如下:
hello.c
#include < stdio.h>
int main( )
{
printf ( "hello world/n " ) ;
return 0 ;
}
可通过
~@ sunhy:~$ gcc hello.c -o hello
来进行编译。
当一个程序有3个文件时。假设有如下几个文件。
hello.c global.h global.c。
源码如下
hello.c
#include < stdio.h>
#include "global.h"
int main( )
{
print( "hello/n " ) ;
return 0 ;
}
global.h
void print ( char * str) ;
global.c
#include < stdio.h>
#include "global.h"
void print( char * str)
{
printf ( "%s" , str) ;
}
一般的编译方式如下
~@ sunhy:~$ gcc global.c hello.c -o hello
或者先编译再连接
~@ sunhy:~$ gcc -o global.c
~@ sunhy:~$ gcc global.o hello.c -o hello
我们也可以使用make命令来对它进行编译,不过这里需要一个makefile文件来描述make为何种方式来编译源代码和链接程序。
makefile文件的缩写规则如下:
TARGET… : PREREQUISITES…
COMMAND
…
…
target:规则的目标
prerequisites:规则的依赖
command:规则的命令行。值得注意的是每一个命令必需是以[TAB]开始。
上面的程序的makefile简单编写如下
Makefile
hello:global.o hello.o
gcc hello.o global.o -o hello
hello.o:hello.c global.h
gcc -c hello.c -o hello.o
global.o:global.c global.h
gcc -c global.c -o global.o
clean:
rm *.o hello
使用make编译
~@ sunhy:~$ make
gcc -c global.c -o global.o
gcc -c hello.c -o hello.o
gcc hello.o global.o -o hello
这里我们可以发现当前目录下生成了hello这个可执行文件。
从上面的Makefile文件中,能看出有三条规则,第一条的目标就生成可执行文件hello,第二条目标就生成hello.o文件,第三条则是生 成global.o文件。而每个冒号后台的部分为生成达到该目标所需要的依赖文件,比如:第一条需要依赖hello.o和global.o这两个文件,第 二条需要依赖hello.c和 global.h这两上文件,第三条需要依赖global.c和global.h这两上文件。接下来下面每条规则下面的一行就是需要执行的命令了。
最后还有一个clean,当用户键入make clean时,就清除所有的*.o文件。
关于make使用上面Makefile文件的工作原理如下:
默认情况下,make执行的是Makefile文件中的第一个规则,此规则的目标也就是整个程序的终极目标,我们上面的文件中生成hello这个可执行文 件就是我们的最终目标,但要生成hello,又必需要依赖于hello.o和global.o这两个链接文件,make在处理这个规则之前,需要先处理 hello所依赖文件的更新规则。
对这些.o(链接文件)规则的处理有三种情况。
1. 目标.o文件不存在,使用其描述规则创建它。如:如果hello.o不存在,则使用gcc -c hello.c -o hello.o来创建它。
2. 目标.o文件存在,但它所信赖的源文件中的任何一个比它都要新,则使用其描述规则创建它。如:hello.c或者global.h有更新时,gcc -c hello.c -o hello.o就得重新执行一次。
3. 目标.o文件存在 ,但它比所依赖的所有源文件都要新时,则什么也不做。
完成了对所有的.o文件的创建和更新后,make将处理第一条规则(终极目标),同样也分三种情况下进行处理。
1. 目标文件”hello”不存在,则执行描述规则创建hello.
2. 目标文件”hello”存在,但它所信赖的文件中的任何一个比它都要新,则根据规则重新链接生成hello文件.
3. 目标文件 “hello”存在,它比它的任何一个链接文件都要新,则什么也不做.