实验二 Makefile 实验 lyun.docx

上传人:b****7 文档编号:9014145 上传时间:2023-02-02 格式:DOCX 页数:15 大小:2.32MB
下载 相关 举报
实验二 Makefile 实验 lyun.docx_第1页
第1页 / 共15页
实验二 Makefile 实验 lyun.docx_第2页
第2页 / 共15页
实验二 Makefile 实验 lyun.docx_第3页
第3页 / 共15页
实验二 Makefile 实验 lyun.docx_第4页
第4页 / 共15页
实验二 Makefile 实验 lyun.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

实验二 Makefile 实验 lyun.docx

《实验二 Makefile 实验 lyun.docx》由会员分享,可在线阅读,更多相关《实验二 Makefile 实验 lyun.docx(15页珍藏版)》请在冰豆网上搜索。

实验二 Makefile 实验 lyun.docx

实验二Makefile实验lyun

Linux实验报告

 

实验名称:

Makefile实验

院系:

物理与机电工程学院

专业班级:

09电子信息工程

(1)班

学号:

2009041507

学生姓名:

大米饭

指导教师:

涂**

完成时间:

2012年11月23日

报告成绩:

评阅意见:

评阅教师日期

 

实验2Makefile实验

【实验目的】

1、了解Makefile的基本概念和基本结构

2、初步掌握编写简单Makefile的方法

3、了解递归Make的编译过程

4、初步掌握利用GNUMake编译应用程序的方法

【实验仪器】

1、装有Linux操作系统的PC机一台;

2、EMIOT-GJX-1物联网高级教学平台

【实验原理】

在Linux或Unix环境下,对于只含有几个源代码文件的小程序(如hello.c)的编译,可以手工键入gcc命令对源代码文件逐个进行编译;然而在大型的项目开发中,可能涉及几十到几百个源文件,采用手工键入的方式进行编译,则非常不方便,而且一旦修改了源代码,尤其头文件发生了的修改,采用手工方式进行编译和维护的工作量相当大,而且容易出错。

所以在Linux或Unix环境下,人们通常利用GNUmake工具来自动完成应用程序的维护和编译工作。

实际上,GNUmake工具通过一个称为Makefile的文件来完成对应用程序的自动维护和编译工作。

Makefile是按照某种脚本语法编写的文本文件,而GNUmake能够对Makefile中指令进行解释并执行编译操作。

Makefile文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

GNUmake工作时的执行步骤如下:

1、读入所有的Makefile。

2、读入被include的其它Makefile。

3、初始化文件中的变量。

4、推导隐晦规则,并分析所有规则。

5、为所有的目标文件创建依赖关系链。

6、根据依赖关系,决定哪些目标要重新生成。

7、执行生成命令。

1-5步为第一个阶段,6-7为第二个阶段。

第一个阶段中,如果定义的变量被使用了,那么,make会把其展开在使用的位置。

但make并不会完全马上展开,make使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。

下面对makefile的相关问题进行简单介绍:

1、Makefile的基本结构

Makefile的一般结构:

target……:

dependency……

command……

结构中各部分的含义:

(1)、target(目标):

一个目标文件,可以是Object文件,也可以是执行文件。

还可以是一个标签(Label)。

(2)、dependency(依赖):

要生成目标文件(target)所依赖哪些文件

(3)、command(命令):

创建项目时需要运行的shell命令(注:

命令(command)部分的每行的缩进必须要使用Tab而不能使用多个空格)。

Makefile实际上是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于dependency中的文件,其生成规则定义在命令command中。

如果依赖文件(dependency)中有一个以上的文件比目标(target)文件要新的话,shell命令(command)所定义的命令就会被执行。

这就是Makefile的规则。

也就是Makefile中最核心的内容。

例如,假设有一个C源文件test.c,该源文件包含有自定义的头文件test.h,则目标文件test.o明确依赖于两个源文件:

test.c和test.h。

如果只希望利用gcc命令来生成test.o目标文件,这时,就可以利用如下的makefile来定义test.o的创建规则:

从上面的例子注意到,第一个字符为#的行表示注释行。

第一个非注释行指定test.o为目标,并且依赖于test.c和test.h文件。

随后的行指定了如何从目标所依赖的文件建立目标。

当test.c或test.h文件在编译之后又被修改,则make工具可自动重新编译test.o,如果在前后两次编译之间,test.c和test.h均没有被修改,而且test.o还存在的话,就没有必要重新编译。

这种依赖关系在多源文件的程序编译中尤其重要。

通过这种依赖关系的定义,make工具可避免许多不必要的编译工作。

一个makefile文件中可定义多个目标,利用maketarget命令可指定要编译的目标,如果不指定目标,则使用第一个目标。

通常,makefile中定义有clean目标,可用来清除编译过程中的中间文件

运行makeclean时,执行rm–f*.o命令,删除编译过程中生成的所有中间文件。

2、Makefile的基本内容

Makefile一般包括包含:

显式规则、隐晦规则、变量定义、文件指示和注释等五个内容。

(1)、显式规则:

显式规则说明如何生成一个或多个的目标文件。

这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

(2)、变量定义。

在Makefile中可以定义一系列的变量,变量一般都是字符串,当Makefile被执行时,变量的值会被扩展到相应的引用位置上。

(3)、隐含规则:

由于GNUmake具有自动推导功能,所以隐晦规则可以比较粗糙地简略地书写Makefile,然后由GNUmake的自动推导功能完成隐晦规则的内容。

(4)、文件指示。

其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。

(5)、注释。

Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:

“\#”。

2.1Makefile中的变量

(1)、Makefile中定义的变量,与C/C++语言中的宏一样,代表一个文本字串,在Makefile被执行时候变量会自动地展开在所使用的地方。

Makefile中的变量可以使用在“目标”,“依赖目标”,“命令”或Makefile的其它部分中。

(2)、Makefile中变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:

”、“#”、“=”或是空字符(空格、回车等)。

(3)、Makefile中变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。

传统的Makefile的变量名是全大写的命名方式

(4)、变量在声明时需要给予初值,而在使用时,需要在变量名前加上“$”符号

上面自定义变量OBJS表示hello.o,当makefile被执行时,变量会在使用它的地方精确地展开,就像C/C++中的宏一样。

上述makfile变量展开后的形式为:

GNUmake的主要预定义变量

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

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

$@——表示规则中的目标文件集。

在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。

$%——仅当目标是函数库文件中,表示规则中的目标成员名。

例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。

如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。

$<——依赖目标中的第一个目标名字。

如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。

注意,其是一个一个取出来的。

$?

——所有比目标新的依赖目标的集合。

以空格分隔。

$^——所有的依赖目标的集合。

以空格分隔。

如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。

$+——这个变量很像"$^",也是所有依赖目标的集合。

只是它不去除重复的依赖目标。

命令的变量。

AR函数库打包程序。

默认命令是“ar”。

AS   汇编语言编译程序。

默认命令是“as”。

CCC语言编译程序。

默认命令是“cc”。

CXX C++语言编译程序。

默认命令是“g++”。

CO   从RCS文件中扩展文件程序。

默认命令是“co”。

CPPC程序的预处理器(输出是标准输出设备)。

默认命令是“$(CC)–E”。

FCFortran和Ratfor的编译器和预处理程序。

默认命令是“f77”。

GET从SCCS文件中扩展文件的程序。

默认命令是“get”。

LEX Lex方法分析器程序(针对于C或Ratfor)。

默认命令是“lex”。

PC   Pascal语言编译程序。

默认命令是“pc”。

YACC   Yacc文法分析器(针对于C程序)。

默认命令是“yacc”。

YACCR   Yacc文法分析器(针对于Ratfor程序)。

默认命令是“yacc–r”。

MAKEINFO   转换Texinfo源文件(.texi)到Info文件程序。

默认命令是“makeinfo”。

TEX   从TeX源文件创建TeXDVI文件的程序。

默认命令是“tex”。

TEXI2DVI   从Texinfo源文件创建军TeXDVI文件的程序。

默认命令是“texi2dvi”。

WEAVE  转换Web到TeX的程序。

默认命令是“weave”。

CWEAVE   转换CWeb到TeX的程序。

默认命令是“cweave”。

TANGLE   转换Web到Pascal语言的程序。

默认命令是“tangle”。

CTANGLE   转换CWeb到C。

默认命令是“ctangle”。

RM删除文件命令。

默认命令是“rm–f”。

命令参数变量:

下面的这些变量都是相关上面的命令的参数。

如果没有指明其默认值,那么其默认值都是空。

ARFLAGS   函数库打包程序AR命令的参数。

默认值是“rv”。

ASFLAGS   汇编语言编译器参数。

(当明显地调用“.s”或“.S”文件时)。

CFLAGS   C语言编译器参数。

CXXFLAGS   C++语言编译器参数。

COFLAGS   RCS命令参数。

CPPFLAGS   C预处理器参数。

(C和Fortran编译器也会用到)。

FFLAGS  Fortran语言编译器参数。

GFLAGS   SCCS“get”程序参数。

LDFLAGS   链接器参数。

(如:

“ld”)

LFLAGS   Lex文法分析器参数。

PFLAGSPascal语言编译器参数。

RFLAGS   Ratfor程序的Fortran编译器参数。

YFLAGS   Yacc文法分析器参数。

2.2隐含规则

GNU make 包含有一些内置的或隐含的规则,这些规则定义了如何从不同的依赖文件建立特定类型的目标。

GNU make 支持两种类型的隐含规则:

(1)、后缀规则(Suffix Rule)。

后缀规则是定义隐含规则的老风格方法。

后缀规则定义了将一个具有某个后缀的文件(例如,.c 文件)转换为具有另外一种后缀的文件(例如,.o 文件)的方法。

每个后缀规则以两个成对出现的后缀名定义,例如,将 .c 文件转换为 .o 文件的后缀规则可定义为:

.c.o:

$(CC) $(CCFLAGS) $(CPPFLAGS) -c -o $@ $<

(2)、 模式规则(pattern rules)。

这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。

模式规则看起来非常类似于正则规则,但在目标名称的前面多了一个 % 号,同时可用来定义目标和依赖文件之间的关系,例如下面的模式规则定义了如何将任意一个 X.c 文件转换为 X.o 文件:

%.c:

%.o

$(CC) $(CCFLAGS) $(CPPFLAGS) -c -o $@ $<

2.3文件引用

在Makefile使用include关键字可以把别的Makefile包含进来,这很像C语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。

例如:

有这样几个Makefile:

a.mk、b.mk、c.mk,还有一个文件叫foo.make,以及一个变量$(bar),其包含了e.mk和f.mk,那么,下面的语句:

   includefoo.make*.mk$(bar)

   等价于:

   includefoo.makea.mkb.mkc.mke.mkf.mk

make命令开始时,会把找寻include所指出的其它Makefile,并把其内容安置在当前的位置。

如果文件都没有指定绝对路径或是相对路径的话,make首先会在当前目录下寻找,如果当前目录下没有找到,那么,make还会在下面的几个目录下找:

(1)如果make执行时,有“-I”或“--include-dir”参数,那么make就会在这个参数所指定的目录下去寻找。

(2)、如果目录/include(一般是:

/usr/local/bin或/usr/include)存在的话,make也会去找。

如果有文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误。

它会继续载入其它的文件,一旦完成makefile的读取,make会再重试这些没有找到,或是不能读取的文件,如果还是不行,make才会出现一条致命信息。

2.4Makefile中的函数

在Makefile中可以使用函数来处理变量,从而让命令或规则更为的灵活和具有智能,函数调用,很像变量的使用,也是以“$”来标识的,函数调用后,函数的返回值可以当做变量来使用。

例如:

'wildcard'的函数,可以展开成一列所有符合由其参数描述的文件名。

文件间以空格间隔。

语法如下:

$(wildcardPATTERN...)

用'wildcard'函数找出目录中所有的".c"文件:

SOURCES=$(wildcard*.c)。

实际上,GNUmake还是许多如字符串处理函数、文件名操作函数等其他函数

3、运行make

3.1Make的执行

一般来说,最简单的就是直接在命令行下输入make命令,GNUmake找寻默认的Makefile的规则是在当前目录下依次找三个文件——“GNUmakefile”、“makefile”和“Makefile”。

其按顺序找这三个文件,一旦找到,就开始读取这个文件并执行,也可以给make命令指定一个特殊名字的Makefile。

要达到这个功能,要求使用make的“-f”或是“--file”参数,例如:

make–fHello.makefile

3.2嵌套执行make

在一些大的工程中,不同模块或是不同功能的源文件放在不同的目录中,可以在每个目录中都书写一个该目录的Makefile,这有利于Makefile变得更加地简洁,而不至于把所有的东西全部写在一个Makefile中,这个技术对于进行模块编译和分段编译有着非常大的好处。

例如,有一个子目录叫subdir,这个目录下有个Makefile文件指明了这个目录下文件的编译规则。

那么总控的Makefile可以书写:

subsystem:

           cdsubdir&&$(MAKE)

如果要传递变量到下级Makefile中,那么可以使用export来声明。

3.3GNUmake命令选项

 GNU make 命令还有一些其他选项,下面给出了这些选项。

命令行选项              含义

-C DIR          在读取 makefile 之前改变到指定的目录 DIR。

-f FILE           以指定的 FILE 文件作为 makefile。

-h                  显示所有的 make 选项。

-i                 忽略所有的命令执行错误。

-I DIR             当包含其他 makefile 文件时,可利用该选项指定搜索目录。

-n                  只打印要执行的命令,但不执行这些命令。

-p                显示 make 变量数据库和隐含规则。

-s                在执行命令时不显示命令。

-w               在处理 makefile 之前和之后,显示工作目录。

-W FILE      假定文件 FILE 已经被修改。

【实验内容】

第1步:

启动终端,切换到~/work目录下,建立一个hello文件夹。

第2步:

切换到hello目录下,利用vi编辑器创建hello.c文件,输入如下内容并保存。

第3步:

手动编译hello应用程序,在hello.c的目录的终端下输入:

emdoor@ubuntu:

~/work/hello$gcc-Wall-chello.c

emdoor@ubuntu:

~/work/hello$gcchello.o-ohello

第4步:

在该目录下执行./hello,运行hello程序

第5步:

编写Makefile文件。

用vi编辑器在hello.c所在的目录下建立Makefile文件,输入

如下内容并保存。

第6步:

用rm命令删除hello、hello.o文件

第7步:

执行make命令,编译hello.c程序。

第8步:

在该目录下执行./hello,运行hello程序。

第9步:

执行makeclean清楚编译结果。

第10步:

重新编辑Makefile文件(红色部分表示修改部分)。

第11步:

重复7、8步,编译并测试结果。

第12步:

多个.c文件的编译。

在/work目录先新建一个hello2目录,并在该目录下用vi命令创建文件hello1.c、hello2.c、hello.h和Makefile。

分别输入如下内容。

/*

第13步:

重复7、8步,编译并测试结果。

第14步:

执行makeclean清楚编译结果。

第15步:

修改Makefile文件(红色部分表示修改部分),并保存。

第16步:

重复7、8步,编译并测试结果。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1