Makefile是什么

Makefile是和make命令一起配合使用的,makefile定义了一系列的规则来指定哪些文件需要先编译、后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,makefile就像一个Shell脚本一样,也可以执行操作系统命令。

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile 定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile 就像一个 Shell 脚本一样,也可以执行操作系统的命令。

Makefile是什么

定义概述

Linux 环境下的程序员如果不会使用 GNU make 来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix 程序员。在 Linux(unix )环境下使用 GNU 的 make 工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一些时间去完成一个或者多个称之为 Makefile 文件的编写。

所要完成的 Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建哪些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写 Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的事就是在 shell 提示符下输入 make 命令。整个工程完全自动编译,极大提高了效率。

make 是一个命令工具,它解释 Makefile 中的指令。在 Makefile 文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像 C 语言有自己的格式、关键字和函数一样。而且在 Makefile 中可以使用系统 shell 所提供的任何命令来完成想要的工作。Makefile 在绝大多数的 IDE 开发环境中都在使用,已经成为一种工程的编译方法。

示例

上述 Makefile 中的“$@”, “$^”, “$<” 称为自动变量。

自动化编译主要功能

Make 工具最主要也是最基本的功能就是通过 makefile 文件来描述源程序之间的相互关系并自动维护编译工作。而 makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器–包括 Windows NT 下的编译器–维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。

在 UNIX 系统中,习惯使用 Makefile 作为 makefile 文件。如果要使用其他文件作为 makefile,则可利用类似下面的 make 命令选项指定 makefile 文件:

make 命令

$ make -f Makefile.debug

例如,一个名为 prog 的程序由三个 C 源文件 filea.c、fileb.c 和 filec

Makefile 文件工程样例

#include “defs”

那么下面的文档就描述了这些文件之间的相互联系:

0 #It is a example for describing makefile 注释行

1 prog : filea.o fileb.o filec.o #指定 prog 由三个目标文件 filea.o、fileb.o 和 filec.o 链接生成

2 cc filea.o fileb.o filec.o -LS -o prog #如何从 prog 所依赖的文件建立可执行文件

3 filea.o : filea.c a.h defs #指定 filea.o 目标文件,以及它们所依赖的.c 和.h 文件以及 defs 文件

4 cc -c filea.c #如何从目标所依赖的文件建立目标,即如何从 filea.c 建立 filea.o

5 fileb.o : fileb.c b.h defs #指定 fileb.o 目标文件,以及它们所依赖的.c 和.h 文件以及 defs 文件

6 cc -c fileb.c #如何从目标所依赖的文件建立目标,即如何从 fileb.c 建立 fileb.o

7 filec.o : filec.c c.h #指定 filec.o 目标文件,以及它们所依赖的.c 和.h 文件

8 cc -c filec.c #如何从目标所依赖的文件建立目标,即如何从 filec.c 建立 filec.o

这个描述文档就是一个简单的 makefile 文件。我们针对上例的代码方面进行一些基础性说明:CC 是一个全局变量,它指定你的 Makefile 所用的编译器,一般默认是 gcc;.o 文件是 unix 下的中间代码目标文件,就如同在 windows 下的.obj 文件一样,在 unix 下生成.o 文件的过程叫编译(compile),将无数.o 文件集合生成可执行文件的过程叫链接(link);有时会在 unix 界面下看到.a 文件,那是 Archive File,相当于 windows 下的库文件 Library File,.a 文件作用是:由于源文件太多(上例是指.c 和.h 文件过多),编译生成的中间目标文件(.o 文件)太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,这个包就是.a 文件。

当 filea.c 或 a.h 文件在编译之后又被修改,则 make 工具可自动重新编译 filea.o,如果在前后两次编译之间,filea.c 和 a.h 均没有被修改,而且 filea.o 还存在的话,就没有必要重新编译。这种依赖关系在多源文件的程序编译中尤其重要。通过这种依赖关系的定义,make 工具可避免许多不必要的编译工作。当然,利用 Shell 脚本也可以达到自动编译的效果,但是,Shell 脚本将全部编译任何源文件,包括哪些不必要重新编译的源文件,而 make 工具则可根据目标上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。

Makefile 文件准备好之后,接着在 Makefile 文件所在的目录下敲入 make 这个命令就可以了,根据 Makefile 文件,以告诉 make 命令需要怎么样的去编译和链接目标程序。

规则

让我们先来粗略地看一看 Makefile 的规则。

target … : prerequisites …

command

目标:依赖

执行指令 …

target 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签(Label)。

① prerequisites 就是,要生成那个 target 所需要的文件或是目标。

② command 也就是 make 需要执行的命令。(任意的 Shell 命令)

这是一个文件的依赖关系,也就是说,target 这一个或多个的目标文件依赖于 prerequisites 中的文件,其生成规则定义在 command 中。说白一点就是说,prerequisites 中如果有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行(command 一定要以 Tab 键开始,否则编译器无法识别 command),减少重复编译,提高了其软件工程管理效率。

文件定义与命令

Makefile 文件作为一种描述文档一般需要包含以下

命令行中执行 makefile

◆宏定义◆ 源文件之间的相互依赖关系

◆ 可执行的命令

Makefile 中允许使用简单的宏指代源文件及其相关编译信息,在 Linux 中也称宏为变量。在引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时就必须加圆括号()。

有效的宏引用

$(CFLAGS)

$Z

$(Z)

其中最后两个引用是完全一致的。

需要注意的是一些宏的预定义变量,在 Unix 系统中,$*、$@、$?和$<四个特殊宏的值在执行命令的过程中会发生相应的变化,而在 GNU make 中则定义了更多的预定义变量。关于预定义变量的详细内容,宏定义的使用可以使我们脱离那些冗长乏味的编译选项,为编写 makefile 文件带来很大的方便。

# Define a macro for the object files

OBJECTS= filea.o fileb.o filec.o

# Define a macro for the library file

LIBES= -LS

# use macros rewrite makefile

prog: $(OBJECTS)

cc $(OBJECTS) $(LIBES) -o prog

此时如果执行不带参数的 make 命令,将连接三个目标文件和库文件 LS;但是如果在 make 命令后带有新的宏定义:

make “LIBES= -LL -LS” #如何实现?

则命令行后面的宏定义将覆盖 makefile 文件中的宏定义。若 LL 也是库文件,此时 make 命令将连接三个目标文件以及两个库文件 LS 和 LL。

在 Unix 系统中没有对常量 NULL 作出明确的定义,因此我们要定义 NULL 字符串时要使用下述宏定义:

STRINGNAME= //这里有待考证

makefile 中的变量(宏)

GNU 的 make 工具除提供有建立目标的基本功能之外,还有许多便于表达依赖性关系

以及建立目标的命令的特色。其中之一就是变量或宏的定义能力。如果你要以相同的编译

选项同时编译十几个 C 源文件,而为每个目标的编译指定冗长的编译选项的话,将是非

常乏味的。但利用简单的变量定义,可避免这种乏味的工作:

# Define macros for name of compiler

CC = gcc

# Define a macr o for the CC flags

CCFLAGS = -D_DEBUG -g -m486

# A rule for building a object file

test.o: test.c test.h

$(CC) -c $(CCFLAGS) test.c

在上面的例子中,CC 和 CCFLAGS 就是 make 的变量。GNU make 通常称之为变量,

而其他 UNIX 的 make 工具称之为宏,实际是同一个东西。在 makefile 中引用变量的值

时,只需变量名之前添加 $ 符号,如上面的 $(CC) 和 $(CCFLAGS)。

GNU make 有许多预定义的变量,这些变量具有特殊的含义,可在规则中使用。表 13-2

给出了一些主要的预定义变量,除这些变量外,GNU make 还将所有的环境变量作为自己

的预定义变量。

预定义变量

含义

$*

不包含扩展名的目标文件名称。

$+

所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。

$<

第一个依赖文件的名称。

$?

所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。

$@

目标的完整名称。

$^

所有的依赖文件,以空格分开,不包含重复的依赖文件。

$%

如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为

(image.o),则 $@ 为 ,而 $% 为 image.o。

AR

归档维护程序的名称,默认值为 ar。

ARFLAGS

归档维护程序的选项。

AS

汇编程序的名称,默认值为 as。

ASFLAGS

汇编程序的选项。

CC

C 编译器的名称,默认值为 cc。

CFLAGS

C 编译器的选项。

CPP

C 预编译器的名称,默认值为 $(CC) -E。

CPPFLAGS

C 预编译的选项。

CXX

C++编译器的名称,默认值为 g++。

CXXFLAGS

C++编译器的选项。

FC

FORTRAN 编译器的名称,默认值为 f77。

FFLAGS

FORTRAN 编译器的选项。

Makefile 以文件名:文件名的形式比较冒号右边的文件是不是较左边的文件有更新,如果有更新则执行下一行的程序代码。因此 Makefile 可以把文件关联起来。

(0)
时间不会说谎  的头像时间不会说谎  

相关推荐

  • 社交代币是什么

    社交代币(Social token)是一类新的代币。由个人或者社区创建的加密货币,大致分为个人代币或者社区代币。建立在社区/社群场景,发行社交代币是为了激励用户为社区创造价值。在社…

  • 信用卡没借钱怎么有欠款

    有可能是信用卡产生的年费,或信用卡还清和没借钱还有欠款,是因为还有一部分消费金额计入下期账单,所以下期还有欠款需要还清。除非用户的所有消费金额都计入本期账单,或者用户选择全额还款,…

  • 九牧马桶型号对照表,如何选择适合自己的马桶型号

    作为一个家庭的必备卫浴设备之一,马桶的选择对于我们的生活质量有着至关重要的作用。而在众多品牌中,九牧马桶以其高品质、高性价比的特点备受消费者的青睐。但是,面对众多的九牧马桶型号,我们该如何选择适合自己的呢?本文将为大家提供九牧马桶型号对照表

    2023年10月14日
  • oppo即将发布的新手机,有哪些值得期待的新功能

    随着科技的不断发展,智能手机已经成为了我们日常生活中必不可少的一部分。而作为智能手机市场的领导者之一,Oppo一直以来都在不断地推陈出新,为用户带来更多的惊喜和体验。近日,Oppo即将发布一款全新的手机,这款手机到底有哪些值得期待的新功能呢

    2023年10月6日
  • 华为Nova12Ultra是麒麟芯片吗?

    最近要说哪款手机最受大家的期待,那么非华为Nova12Ultra莫属了。这是华为Nova12系列中最顶配的版本。但因为是中端系列的缘故,价格还是要比华为Mate60系列便宜不少的。而且根据爆料,华为Nova12Ultra的整体配置和华为

    2024年1月30日
  • 现在还有小电视机卖,哪里可以买到

    随着科技的不断发展,大屏幕电视机已经成为了家庭娱乐的主流选择。然而,对于一些老年人或者特定的场合来说,小电视机仍然是不可或缺的存在。那么问题来了,现在还有小电视机卖吗?哪里可以买到呢?本文将为您一一解答。一、电子产品专卖店首先,我们可以

    2023年11月26日
  • 联想电脑一体机a320怎么样,值得购买吗?

    本文目录一览联想电脑一体机a320怎么样(值得购买吗?)外观设计性能表现使用体验总结联想电脑一体机a320怎么样(值得购买吗?)联想电脑一体机a320是一款非常受欢迎的电脑产品,它的外观设计时尚大方,性能也非常出色。那么,联想电脑

    2023年12月29日
  • 各品牌3070ti性能排行,哪个品牌的性能最强?

    随着游戏的发展,对于电脑显卡的要求也越来越高。NVIDIARTX30系列显卡的推出,给游戏玩家带来了更加流畅的游戏体验。其中,3070ti显卡是一款性价比较高的显卡,那么各品牌3070ti性能排行中哪个品牌的性能最强呢?下面我们来一一分

    2024年1月1日
  • 富士x100是定焦吗,解析富士x100的镜头特性

    富士x100是一款备受瞩目的相机,它的镜头特性备受关注。很多人都在问,富士x100是定焦吗?今天,我们就来解析一下富士x100的镜头特性,看看它到底是不是定焦。1.富士x100的镜头介绍富士x100采用的是23mmf/2镜头,等效于3

    2023年12月1日
  • 三星s21换屏,需要注意哪些细节

    如果你的三星s21手机屏幕出现了裂痕或者其他损坏,那么你可能需要更换屏幕。但是,在更换屏幕之前,你需要注意一些细节,以免损坏其他部件或者使手机更加不稳定。在这篇文章中,我们将为你提供三星s21换屏的详细步骤和需要注意的细节。步骤一:备份数

    2024年2月3日
  • 信用卡如何快速提额

    信用卡涨额度最快的方法是申请临时额度。信用卡固定额度的增长需要一定的间隔时间,而申请临时额度则没有这个时间制约。用户每月都可以申请临时额度,临时额度只要申请成功,信用卡可用额度就会…

  • 惠普服务器指示灯含义,如何正确解读和诊断

    惠普服务器是企业级服务器的代表之一,其性能稳定、安全可靠,备受用户青睐。在使用惠普服务器的过程中,服务器的指示灯是非常重要的一个组成部分。服务器指示灯的亮灭状态可以帮助管理员诊断服务器的健康状态,及时发现故障并进行修复。本文将为大家介绍惠普

    2023年11月26日
  • 电视音响连接线,如何正确选择和连接

    电视和音响是我们生活中不可或缺的一部分,它们让我们享受到更好的视听体验,而连接线则是它们之间传输信号的关键。然而,市场上有各种各样的连接线,如何正确选择和连接呢?本文将为大家介绍如何正确选择和连接电视音响连接线。一、如何选择电视音响连接线

    2024年1月28日
  • CT变频器M702,如何正确选择和使用

    作为一种常见的电力设备,变频器被广泛应用于工业生产中。而在变频器中,CT变频器M702是一款常见的型号。在选择和使用CT变频器M702时,有哪些需要注意的地方呢?本文将为您详细介绍。一、CT变频器M702的基本介绍CT变频器M702是一

    2023年12月29日
  • 韩版三星s10e和国行有什么区别,详细对比分析

    作为三星旗下的一款中高端手机,S10e在发布之后引起了不少的关注。而在S10e的销售过程中,我们会发现同样是S10e,有韩版和国行两种版本。那么,这两种版本有什么区别呢?下面我们就来详细对比分析一下。外观设计方面首先,我们来看看外观设计

    2024年2月8日

发表回复

登录后才能评论