使用make编译
本章介绍make编译的一些基本知识,并通过示例进行实际演示。更多的make知识请通过make --help命令查询,或者查看GNU官方文档。
简介
GNU make实用程序(通常缩写为make)是一种用于控制从源文件生成可执行文件的工具。 make会自动确定复杂程序的哪些部分已更改并需要重新编译。 make使用称为Makefile的配置文件来控制程序的构建方式。
基本规则
文件类型
makefile文件中可能用到的文件类型如表1所示。
表 1 文件类型
可执行文件,但可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。如果没有给出可执行文件的名字,GCC将生成一个名为a.out的文件。 |
make工作流程
使用make由源代码文件生成可执行文件,需要经过如下步骤:
- make命令会读入Makefile文件,包括当前目录下命名为“GNUmakefile” 、“makefile” 、“Makefile”的文件、被include的makefile文件、参数-f、--file、--makefile指定的规则文件。
- 初始化变量。
- 推导隐含规则,分析依赖关系,并创建依赖关系链。
- 根据依赖关系链,决定哪些目标需要重新生成。
- 执行生成命令,最终输出终极文件。
make选项
make命令格式为:make [option]... [target]...
其中:
option :参数选项。
target :Makefile中指定的目标。
常用make的 option 取值如表2所示。
表 2 常用的make选项
Makefile
make是通过Makefile文件获取如何编译、链接和安装、清理的方法,从而实现将源代码文件生成可执行文件和其他相关文件的工具。因此,Makefile中描述了整个工程的编译和链接等规则,其中包含了哪些文件需要编译,哪些文件不需要编译,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重建等等。Makefile文件让工程编译实现了自动化,不需要每次都手动输入一堆源文件和参数。
本章简单介绍Makefile文件的结构和主要内容,更多Makefile的内容请通过info make命令查询。
Makefile结构
Makefile文件结构如下所示:
targets:prerequisites
command
或者是:
targets:prerequisites;command
command
其中:
- targets :目标,可以是目标文件、可执行文件或标签。
- prerequisites :依赖文件,生成targets需要的文件或者是目标。可以是多个,也可以没有。
- command :make需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。
- 目标和依赖文件之间要使用“:”分隔,命令的开始一定要按“Tab”。
Makefile文件结构表明了输出的目标,输出目标的依赖对象和生成目标需要执行的命令。
Makefile主要内容
一个Makefile文件主要由以下内容组成:
显式规则
明确写出来的依赖关系,如要生成的文件,文件的依赖文件,生成的命令。
隐含规则
由make自动推导的规则,make命令支持自动推导功能。
变量的定义
文件指示
文件指示包括三部分:
- include 其他 Makefile,如include xx.md。
- 选择执行,如#ifdef。
- 定义多行命令,如define...endef。
注释
以 “#” 开头。
示例
使用Makefile实现编译的示例
cd到代码目录,以目录“~/code”进行举例。
$ cd ~/code
创建1个头文件hello.h和2个函数hello.c、main.c。
$ vi hello.h $ vi hello.c $ vi main.c
hello.h代码内容示例:
#pragma once #include <stdio.h> void hello();
hello.c代码内容示例:
#include "hello.h" void hello() { int i=1; while(i<5) { printf("The %dth say hello.\n", i); i++; } }
main.c代码内容示例:
#include "hello.h" #include <stdio.h> int main() { hello(); return 0; }
创建Makefile文件。
$ vi Makefile
Makefile文件内容示例:
main:main.o hello.o gcc -o main main.o hello.o main.o:main.c gcc -c main.c hello.o:hello.c gcc -c hello.c clean: rm -f hello.o main.o main
执行make命令。
$ make
命令执行后,会打印Makefile中执行的命令。如果不需要打印该信息,可以在执行make命令时加上参数-s。
gcc -c main.c
gcc -c hello.c
gcc -o main main.o hello.o
执行./main目标。
$ ./main
命令执行后,打印如下信息:
The 1th say hello.
The 2th say hello.
The 3th say hello.
The 4th say hello.