首页 百科知识 使用管理项目

使用管理项目

时间:2022-10-18 百科知识 版权反馈
【摘要】:在编写小型的Linux应用程序时,一般情况下只会有少数几个源文件。为此,Linux专门为软件开发提供了一个自动化管理工具GNU make。Make凭借本身的优势,可在所有的Unix系统中被找到。Makefile文件是一个文本文件,它用于描述整个项目和各个文件之间的依赖关系。注意到,makefile中命令行必须以单个的TAB字符进行缩进,不能是空格。编写完毕,当使用该makefile文件,输入make。如果安装了新版本的autoconf,可以使用选项一force调用autoreconf而重新创建所有的文件。

10.4.4 使用GNUmake管理项目

(1)项目组成

一般地,一个项目多数情况下都由多个源程序文件组成,编译时需要逐个把它们编译成目标文件,然后统一链接成可执行文件。下面的例子中将程序Hello World分割成3个文件: “hello.c”,“hello_fn.c”和头文件“hello.h”,如下所示:

①文件“hello.c”的内容:

img490

②主程序中包含有头文件“hello.h”的内容:

void hello(const char*name);

该头文件包含函数hello的声明。不需要在“hello.c”文件中包含系统头文件“stdio.h”来声明函数printf,因为“hello.c”没有直接调用printf。声明只用了一行就指定了函数hello的原型。

③函数hello的定义在文件“hello_fn.c”的内容:

img491

注意:

语句#include“FILE.h”与#include<FILE.h>有所不同:前者在搜索系统头文件目录之前将先在当前目录中搜索文件“FILE.h”,后者只搜索系统头文件而不查看当前目录。

编译时可以采用以下命令:

img492

使用选项“-o”为可执行文件指定名字为hello。头文件“hello.h”并未在命令行中指定。因为源文件中的的#include“hello.h”指示符使得编译器自动将其包含到合适的位置。

编译完毕,执行文件名:

$./ hello

Hello,world!

在编写小型的Linux应用程序时,一般情况下只会有少数几个源文件。这样程序员能够很容易地理清它们之间的包含和引用关系。但是,随着软件项目逐渐变大,对源文件的处理也将变得越来越复杂起来。此时单纯依赖手工方式进行管理的做法就显得有些力不从心。为此,Linux专门为软件开发提供了一个自动化管理工具GNU make。通过它,程序员可以很方便地管理软件编译的内容、方式和时机,从而使程序员能够把主要精力集中在代码的编写上。

make将整个软件项目的代码分开放在几个小的源文件里,在改动其中一个文件的时候,可以只对该文件重新进行编译,然后重新链接所有的目标文件。对于那些由许多源文件组成的大型软件项目来说,全部重新进行编译需要花费很长的时间,而采用这种项目管理方法则可以极大地提高工作效率,让原本复杂繁琐的开发工作变得简单。make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并链接生成可执行文件,并要求定义源文件之间的依赖关系。

(2) Makefile文件

Make凭借本身的优势,可在所有的Unix系统中被找到。要了解关于Gnumake的更多信息,请参考Richard M.Stallman和Roland McGrath编写的GNU Make手册。

Makefile文件是一个文本文件,它用于描述整个项目和各个文件之间的依赖关系。它由多个规则组成,每个规则又包含了目标(target)、依赖列表(dependencies)和相关命令组成。这些命令负责完成文件的编译、链接、复制、安装、清理等各种操作。

Make从makefile(默认是当前目录下的名为“Makefile”的文件)中读取项目的描述。makefile指定了一系列目标(比如可执行文件)和依赖(比如对象文件和源文件)的编译规则,makefile文件的规则遵循以下结构:

img493

对每一个目标,make检查其对应的依赖文件修改时间来确定该目标是否需要利用对应的命令重新建立。注意到,makefile中命令行必须以单个的TAB字符进行缩进,不能是空格。

GNU Make包含许多默认的规则(参考隐含规则)来简化makefile的构建。比如说,它们指定“.o”文件可以通过编译“.c”文件得到,可执行文件可以通过将“.o”链接到一起获得。隐含规则通过被叫做make变量的东西所指定,比如CC(C语言编译器)和CFLAGS(C程序的编译选项);在makefile文件中它们通过独占一行的变量=值的形式被设置。对C++,其等价的变量是CXX和CXXFLAGS,而变量CPPFLAGS则是编译预处理选项。

make使用makefile自动维护编译工作,其操作如下三个步骤(以上一节hello项目为例):

①Makefile文件内容:

img494

读解该文件内容:使用C语言编译器gcc,和编译选项“-Wall”,从对象文件“hello.o”和“hello_fn.o”生成目标可执行文件hello(文件“hello.o”和“hello_fn.o”通过隐含规则分别由“hello.c”和“hello_fn.c”生成)。目标clean没有依赖文件,它只是简单地移除所有编译生成的文件。rm命令的选项“-f”(force)不提示产生的错误消息。另外建议:如果包含main函数的cpp文件为K.cpp,makefile中最好把可执行文件名也写成K。

②调用make。编写完毕,当使用该makefile文件,输入make。如果不使用参数调用make时,makefile文件中的第一个目标被建立,从而生成可执行文件hello,如下所示:

img495

img496

如果一个源文件被修改,而需要重新生成可执行文件,只要再输入make命令即可。通过检查目标文件和依赖文件的时间戳程序,make可识别哪些文件已经修改并依据对应的规则更新其对应的目标文件,如下所示:

img497

③使用make clean命令

可以使用make clean命令移除make生成的文件,如下所示:

$ make clean

rm-f hello hello.o hello_fn.o

一个专业的makefile文件通常包含用于安装(make install)和测试(make check)等额外的目标。对任何大些的程序都使用make是很有必要的。

(3)使用autoconf。如果有大量由autoconf生成的。Onfigure脚本,程序autoreconf可以保留一些工作。它重复地运行autoconf(在适当的情况下还运行autoheader)以重新创建以当前目录为根的目录树的autoconf configure脚本和配置头文件。在默认情况下,它只重新创建那些比对应的configure.in或者(如果出现) aclocal.m4旧的文件。在文件没有被改变的情况下,autoheade并不改变它的输出文件的时间戳(timestamp),这是为了使工作量最小化,修改时间戳是不必要的。如果安装了新版本的autoconf,可以使用选项一force调用autoreconf而重新创建所有的文件。

注释:

●Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中记录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。

●Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动发现最终的生成文件已经过时,而重新编译相应的模块。

●Makefile的基本结构不是很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的是否符合惯例,而且自己写的Makefile经常和自己的开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改。这样就造成了手工书写Makefile的诸多问题,automake恰好能很好地解决这些问题。

●使用automake,程序开发人员只需要写一些简单的含有预定义宏的文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的Makefile。下面将详细介绍Makefile的automake生成方法。

(4) GNUmake管理范例

使用简单的程序hello进行演示,首先新建三个文件如下:

hello.c

configure.in

Makefile.am

然后执行命令:

aclocal; autoconf; automake--add-missing;./configure;make;./hello

可以看到Makefile被产生出来,而且可以将hello.c编译通过。

详细的操作过程如下:

①创建目录,在当前目录下建一个hello目录,用来存放hello程序及相关文件,如在/ home/hncst下:

$ mkdir hello

$ cd hello

②用编辑器写一个hello.c文件,如命令:vi hello.c。使用下面的代码作为hello.c的内容,完成后保存退出。

intmain(int argc,char**argv)

{

printf(“Hello,Welcome to HNCST!\n”);

return 0;

}

③使用autoscan命令,根据目录下的源代码生成一个configure.in的模板文件。命令如下:

$ autoscan

$ ls

autoscan.log configure.scan hello.c

执行后在hellowrold目录下会生成一个文件:configure.scan,可以参照作为configure.in的模板。

④现在将configure.scan改名为configure.in,并且编辑它,按下面的内容修改,去掉无关的语句:

img498

img499

⑤执行命令aclocal和autoconf,分别会产生aclocal.m4及configure两个文件:

img500

注释:

●configure.in内容是一些宏定义,这些宏经autoconf处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。

●autoconf是用来生成自动配置软件源代码脚本(configure)的工具。configure脚本能独立于autoconf运行,且在运行的过程中,不需要用户的干预。

●要生成configure文件,必须告诉autoconf如何找到所用的宏。方法是使用aclocal程序来生成aclocal.m4。

●aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal是一个perl脚本程序,它的定义是:“aclocal-create aclocal.m4 by scanning configure.ac”。

●autoconf从configure.in这个列举编译软件时所需要各种参数的模板文件中创建configure。

●autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本。

●m4是一个宏处理器。将输入拷贝到输出,同时将宏展开。宏可以是内嵌的,也可以是用户定义的。除了可以展开宏,m4还有一些内建的函数,用来引用文件,执行命令,整数运算,文本操作,循环等。m4既可以作为编译器的前端,也可以单独作为一个宏处理器。

⑥新建Makefile.am文件,命令如下:

$ viMakefile.am

Makefile.am文件如下:

AUTOMAKE_OPTIONS=foreign

bin_PROGRAMS=hello

hello_SOURCES=hello.c

automake会根据Makefile.am来自动生成Makefile.in。Makefile.am中定义的宏和目标,会指导automake生成指定的代码。例如,宏bin_PROGRAMS将导致编译和连接的目标被生成。

⑦运行automake,根据Makefile.am文件会产生一些文件,包含最重要的Makefile.in。

img501

⑧执行configure生成Makefile

img502

⑨使用Makefile编译代码

img503

img504

⑩运行hello

img505

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈