`
helloyesyes
  • 浏览: 1333096 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

开发工具

阅读更多
在这一章,我们将会讨论在Linux系统上可用的程序开发工具,其中一些在Unix系统上也可用。除了必须的编译器与调试器以外,Linux提供了一个工具集,其中的每一个工具都完成单独的工作,并且允许开发者以新的方式对这些工具进行组合。这就是Linux所继承的Unix哲学的一部分。在这里,我们将会讨论其中的一些重要工具,并且会讨论使用这些工具解决问题的例子,包括:

make命令以及makefile
使用RCS与CVS进行源代码控制
编写手册页
使用patch与tar发布软件
开发环境

多源代码的问题

当我们编写小程序时,许多人都是简单的在编辑后通过重新编译所有的文件重新构建我们的程序。然而,对于大程序,这种简单构建方法的问题就变得明显了。编辑-编译-测试的循环时间将会变长。即使是最为耐心的程序员也会希望避免当只修改一个文件时而编译所有的文件。

当创建多个头文件并且在不同的源文件中包含多个头文件时就会出现一个更为困难的问题。假设我们有三个头文件a.h,b.h以及c.h,和C源文件main.c,2.c以及3.c。而我们会具有如下的包含关系:

/* main.c */
#include “a.h”
...
/* 2.c */
#include “a.h”
#include “b.h”
...
/* 3.c */
#include “b.h”
#include “c.h”
...

如果程序员修改了c.h,文件main.c以及2.c并不需要重新编译,因为他们并不依赖于这个头文件。文件3.c依赖于c.h,所以如果c.h被修改了,那么他就应被重新编译。然而,如果b.h被修改了,而程序员忘记重新编译2.c,那么所得到的程序也许就不会正常工作。

make程序通过确保修改所影响的所有文件在需要时进行重新编译来解决所有这些问题。

make命令与Makefile

然而,正如我们所看到的,make命令有许多内建的知识,他本身并不知道如何构建我们的程序。我们必须提供一个文件来告诉make我们的程序是如何组织的。这个文件就是makefile。

makefile文件通常与工程的源文件位于同一个目录中。我们可以同时在我们机子上有多个不同的makefile文件。确实,如果我们有一个非常大的工程,我们也许会选择对于工程的不同部分使用单独的makefile文件进行管理。

make命令以及makefile文件的组合提供了一个强大的工具来进行工程的管理。他通常不仅用于控制源代码的编译,而且也用于准备手册页以及将程序安装到目标目录。

makefile文件的语法

一个makefile文件由一组依赖与规则组成。一个依赖具有一个目标(将要创建的文件)以及他所依赖的源文件集合。规则描述了由依赖文件如何创建目标文件。通常,目标文件是一个可执行文件。

makefile文件由make命令来执行,从而决定目标文件或是要创建的文件,然后比较源文件的日期与时间用于决定调用哪条规则来构建目标。通常,在构建最终的目标之前必须创建一些中间目标。make命令使用makefile文件来确定目标构建的正确顺序以及规则调用的正确顺序。

make选项与参数

make程序本身有多个选项。最常用的三个为:

-k,这个选项会通知make命令,当发现一个错误时会继续执行,而不是在检测到第一个问题时立即退出。例如,我们可以使用这个选项检测出哪个文件编译失败。
-n,这个选项会使得make命令打印出此命令将会做的事情而不会实际执行。
-f <filename>,这个选项会通知make命令使用哪个文件作为makefile文件。如果我们没有使用这个选项,make首先在会当前目录查找名为makefile的文件。如果这个文件不存在,他就会查找Makefile。按约定,Linux程序使用Makefile。这会使用makefile文件在一个满是小写字母名字的目录中第一个出现。

要告诉make来构建一个特定目录,通常是一个可执行文件,我们可以将目标名字作为参数传递给make命令。如果没有这样做,make就会试着构建makefile文件中的第一个目标。许多程序在其makefile文件中将all指定为第一个目标,然后列出其他的all所依赖的目标。这个约定可以很清晰的指出当没有指定目标时makefile应尝试构建的默认目标。我们建议遵守这个约定。

依赖

依赖指出最终程序中的每一个文件如何与源文件相关。在我们本章开始时所显示的例子中,我们指出我们最终的程序依赖于main.o,2.o以及3.o;类似的main.o依赖于main.c与a.h等。所以main.会受到main.c和a.h修改的影响,如果这两个文件中的任何一个发生变化,都需要通过重新编译main.c来重新创建main.o。

在makefile文件中,我们编写规则的格式如下:目标名,冒号,空格或是tab,然后是以空格或是tab分隔的用于创建目标文件的列表。我们例子中的依赖列表如下:

myapp: main.o 2.o 3.o
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h

这表明myapp依赖于main.o,2.o以及3.o,而main.o依赖于main.c以及a.h,等等。

依赖集合指出了一个层次显示了源文件之间如何彼此相关。我们可以很容易的看出,如果b.h发生变化,那么我们需要重新修正2.o以及3.o,而2.o与3.o发生了变化,我们也需要重新构建myapp。

如果我们希望编构建多个文件,那么我们可以使用伪目标all。假设我们的程序由二进制文件myapp与手册页myapp.1构成。我们可以用下面的语句来指定目标:

all: myapp myapp.1

再一次声明,如果我们没有指定all目标,make只是简单的创建他在makefile中查找到的第一个目标。

规则

makefile文件中的第二部分指定了用于描述如何创建一个目标的规则。在我们前面部分的例子中,在make命令之后应该使用哪个命令来重新构建2.o呢?看起来也许只是简单的使用gcc -c 2.c就足够了(而且,正如我们在后面将会看到的,make确实知道许多默认的规则),但是如果我们需要指定一个include目录,或是设置用于以后调试的符号信息选项时应怎么办呢?我们可以通过在makefile文件中显示的指定规则来做到。

注:在这里我们需要提示makefile文件一个非常奇怪的语法:一个空格与一个tab之间有区别。所有规则所在的行必须以一个tab开始;而不能以一个空格开始。因为多个空格与一个tab看起来很相似,而且因为在绝大多数的其他的Linux程序中在空格与tab之间并没有区别,所以如果不加区分就会出现问题。同时,makefile文件中一行结束处的空格也会使得make命令失败。然而,这是一个历史问题,而且已经有许多的makefile文件在尝试改进这个问题,所以我们要小心。幸运的是,当make命令不能工作时,通常一个很明显的问题就是丢失了tab。

试验--一个简单的Makefile

大多数规则由本可以在命令行输入的简单命令组成。对于我们的例子而言,我们可以创建我们的第一个makefile文件,Makefile1:

myapp: main.o 2.o 3.o
gcc -o myapp main.o 2.o 3.o
main.o: main.c a.h
gcc -c main.c
2.o: 2.c a.h b.h
gcc -c 2.c
3.o: 3.c b.h c.h
gcc -c 3.c

我们需要使用-f选项来调用我们的make命令,因为我们的makefile文件并不是通常默认的makefile或是Makefile。如果我们在一个并不包含任何源码的目录中调用这个代码,我们就会得到下面的信息:

$ make -f Makefile1
make: *** No rule to make target ‘main.c’, needed by ‘main.o’.
$

make命令认为makefile文件中的第一个目录myapp是我们希望创建的文件。然后他会查找其他的依赖,并且会确定需要一个名为main.c的文件。因为我们还没有创建这个文件,而makefile也并不知道如何创建这个文件,所以make命令就会报告错误。下面我们创建这些源文件并且再次尝试。因为我们对于结果并不感兴趣,所以这些文件可以非常简单。头文件实际上为空,所以我们使用touch命令来创建这些文件。

$ touch a.h
$ touch b.h
$ touch c.h

main.c包含main函数,并且会调用function_two与function_three。其他的两个文件定义了function_two与function_three。源文件包含#include行来指定头文件,所以他们会依赖所包含的头文件的内容。这并不是一个程序,但是我们在这里列出相应的部分:

/* main.c */
#include <stdlib.h>
#include “a.h”
extern void function_two();
extern void function_three();
int main()
{
function_two();
function_three();
exit (EXIT_SUCCESS);
}
/* 2.c */
#include “a.h”
#include “b.h”
void function_two() {
}
/* 3.c */
#include “b.h”
#include “c.h”
void function_three() {
}

下面我们再试一次:

$ make
gcc -c
gcc -c
gcc -c
gcc -o
$

这就是一次成功的make。

工作原理

make命令处理makefile文件中的依赖部分,并且确定需要创建的文件以及创建的顺序。尽管我们首先列出了如何创建myapp,make可以确定创建文件的正确顺序。然后他会调用我们在这些规则中所指定的创建这些文件的命令。make命令会在执行相应的命令时显示这些命令。现在我们可以测试我们的makefile文件来确定他是否正确的处理了b.h的修改。

$ touch b.h
$ make -f Makefile1
gcc -c 2.c
gcc -c 3.c
gcc -o myapp main.o 2.o 3.o
$

make命令已经读入我们的makefile文件,确定重新构建myapp所需要的最小数量的命令,并且以正确的顺序执行这些命令。下面我们来看一下如果我们删除一个目标文件时会发生什么:

$ rm 2.o
$ make -f Makefile1
gcc -c 2.c
gcc -o myapp main.o 2.o 3.o
$

再一次,make正确的确定了所需要的动作。
分享到:
评论

相关推荐

    斯凯开发工具!mrp软件开发!mtk平台开发工具

    斯凯开发工具是一款专为MTK(MediaTek)平台设计的软件开发套件,用于MRP(Mobile RunTime Package)应用程序的开发。MRP是一种基于Java的轻量级应用程序格式,广泛应用于早期的智能手机和一些非主流品牌手机,尤其...

    NES游戏开发工具 NES游戏编程 NES游戏教程

    【标题】"NES游戏开发工具 NES游戏编程 NES游戏教程"涉及的是8位家用游戏机——Nintendo Entertainment System(NES)的游戏制作技术。NES是1980年代末至1990年代初流行的家用游戏机,它承载了一代人的游戏记忆。这...

    MCGS_脚本驱动开发工具

    《MCGS脚本驱动开发工具详解》 MCGS(Monitor and Control for General System)是一款广泛应用于工业自动化领域的监控组态软件。它的脚本驱动开发工具为用户提供了强大的自定义功能,使得用户可以根据实际需求编写...

    开发工具开发工具开发工具开发工具

    "开发工具开发工具开发工具开发工具"这个标题暗示了我们将深入探讨各类开发工具的功能、重要性以及如何选择和使用它们。 描述中的重复性表明了开发工具对于开发者的重要性,因为它们涵盖了编码、调试、版本控制、...

    开发工具集成JIRA插件.docx

    JIRA 插件开发工具集成指南 JIRA 是一个流行的项目管理和 issue 跟踪工具,广泛应用于软件开发、项目管理等领域。为了提高开发效率和团队协作,集成 JIRA 插件于开发工具中显得尤为重要。本文将详细介绍 JIRA 插件...

    IM安卓开发工具箱imakit9.13更新.zip

    IM安卓开发工具箱imakit是一款专为Android开发者设计的强大工具,尤其在制作和管理刷机包方面具有显著优势。最新版本imakit 9.13带来了更多改进和新功能,进一步提升了开发者的效率和体验。 首先,imakit的核心功能...

    开发工具 asm-5.1

    开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具 asm-5.1开发工具...

    开发工具 customer

    开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 customer开发工具 ...

    软件开发工具串讲资料

    软件开发工具是软件工程师在开发过程中使用的各类辅助程序,它们旨在提升软件开发的质量、效率和管理。软件开发工具不仅包含编程语言,还涉及项目管理、文档生成、测试、调试等多个方面。这些工具可以帮助开发者更好...

    MCGS脚本驱动开发工具使用指导手册.zip_MCGS 驱动开发_MCGS脚本编写_MCGS脚本驱动开发工具使用指导手册_mc

    MCGS脚本驱动开发工具,可以学习开发基于MCGS嵌入式组态软件相关的仪表驱动,可直接用MCGS触摸屏和仪表进行通讯交互。 脚本驱动是一种使用MCGS增强语言编写的设备驱动程序。 目的,是给用户提供一种与传统MCGS...

    开发工具 ant-1.9.6

    开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6开发工具 ant-1.9.6...

    ROM开发工具箱(安卓9解包修包专用工具)

    ROM开发工具箱(安卓9解包修包专用工具)

    开发工具 login 开发工具 login

    开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发工具 login开发...

    MES系统开发工具v5.207

    【MES系统开发工具v5.207】是一款专为快速构建企业系统设计的专业开发工具,旨在简化系统开发过程,提高开发效率,并且允许开发者根据企业的个性化需求进行自由构建。这款工具以其用户友好的界面和强大的功能,成为...

    Linux开发工具箱--项目开发的最有效途径.pdf

    《Linux开发工具箱:项目开发的最有效途径》将系统性地介绍GNU/Linux的开源工具,并通过可以被读者容易修改的简明示例说明如何使用这些工具,以满足读者的实际需求。《Linux开发工具箱:项目开发的最有效途径》首先...

    U8+快速开发工具.7z

    U8快速开发工具是针对客户化开发的特点,基于U8平台而开发的一套简化、快速、高效的U8单据(非UAP表单)开发工具。使用快速开发工具开发的单据与U8标准单据风格一致,可通过数据库脚本的简单调整设置单据上字段格式...

    计算机信息管理(独立本科段)3173软件开发工具附件1-PowerBuilder应用开发工具例程(源码+发布包)

    书 名:3173 软件开发工具 自考教材 全国高等教育自学考试指定教材 计算机信息管理(独立本科段) 组 编:全国高等教育自学考试指导委员会 出版社:经济科学出版社 版 次:2000年2月第1版 2008年4月第8次印刷 作 者: 陈...

    开发工具 FontAwesome

    开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome开发工具 FontAwesome...

    微信小程序开发工具20180308

    微信小程序开发工具最新版本,当前更新时间为20180308,官方工具请放行使用。

    开发工具 Page 开发工具 Page

    开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发工具 Page开发...

Global site tag (gtag.js) - Google Analytics