引言
gcc编译几个或几十个源程序时没有问题,当源程序有有几百个或上千个时,再用gcc就很不方便了,而且当程序有小改动时,gcc编译四阶段(预处理、编译、汇编和链接)中的链接阶段极其繁琐。linux系统提供了一个功能强大的程序维护工具make,利用该工具,只需要定义一个makefile的文件,在makefile文件中,定义好文件编译顺序和重新编译,makefile就可以实现自动编译。写好makefile文件后,执行make指令,就可以按照之前makefile的规则编译整个应用程序。make工具通常使用在工程编译和程序链接上。
gcc
介绍make维护工具程序前,先介绍一下Linux系统下的C语言编译器GCC。
gcc编译过程
GCC编译程序时,编译过程可以被细分为四个阶段:
- 预处理(Pre-Processing);
- 编译(Compiling);
- 汇编(Assembing);
- 链接(Linking);
在这个四个阶段可以设置选项生成扩展名为 “.i”的编译预处理源代码。扩展名为“.s"的汇编代码和扩展名为“.o” 的目标文件。
gcc -E hello.c -o hello.i //预处理阶段
gcc -S hello.i -o hello.s //编译阶段
gcc -c hello.s -o hello.o //汇编阶段
gcc hello.o -o hello //链接阶段
make的工作机制
make的主要工作 执行新的目标程序的各个步骤,即自动检测一个大型程序那些需要重新编译,然后发出命令重新编译。
make编译过程
- 依次读入每个makefile文件;
- 初始化文件中的变量;
- 推导隐式规则,并分析所有规则;
- 为所有目标文件创建依赖关系链;
- 根据依赖关系和时间数据,确定哪些文件重新生成;
- 执行相应生成命令。
makefile
make一个大型程序,必须创建一个makefile文件,makefile告诉make通过GCC如何编译和链接程序。makefile有自己的格式–书写格式、关键字、函数。而且makefile文件名首字母大写:Makefile
通用格式:
目标:依赖文件
[TAB]命令
#sample Makefile
OBJ= hello.o main.o #定义变量OBJ
edit : ${OBJ} #edit 为目标程序
gcc -o edit main.o hello.o
main.o : main.c
gcc -c main.c
hello.o: hello.c hello.h
gcc -c hello.c
clean: #make clean 删除可执行程序和edit程序
rm $(OBJ) edit
Makefile目录下的文件
主函数main.c
#include <stdio.h>
#include "hello.h"
int main(void)
{
hi();
}
子程序hello.c
#include <stdio.h>
#include "hello.h"
int hi(void);
int hi(void)
{
printf("hello world\n");
}
头文件hello.h
#ifndef HELLO_H
#define HELLO_H
int hi();
#endif
运行结果
hz@titan1:~/c_program/linux/make$ ls
hello.c hello.h main.c Makefile
hz@titan1:~/c_program/linux/make$ make
gcc -c hello.c
gcc -c main.c
gcc -o edit main.o hello.o
hz@titan1:~/c_program/linux/make$ ls
edit hello.c hello.h hello.o main.c main.o Makefile
hz@titan1:~/c_program/linux/make$ ./edit
hello world