《beginning linux programming 4th edition》中文翻译(一)_naiveC的专栏-程序员宅基地

技术标签: gcc  linux  makefile  工具  工作  unix  

1.  译序 

《beginning linux programming 》是一本讲述Linux应用开发的一本挺不错的参考书,目前已经是第四版(2008),由于工作需用到Linux开发,所以在网上找到该书。但目前并没有发现第四版有中文的翻译。所以本人试着翻译了几章内容,现在贡献出来供大家share。

 

2. 第九章 开发工具(Development Tools)

    本章介绍在Linux环境中开发程序所用到的工具,其中有一些在UNIX系统中也可使用。除了明显必须的编译调试器以外,Linux提供一个工具集,工具集中的每个工具都完成一项工作,这使得开发者能够创新性的将这些工具组合起来完成工作。这也是Linux继承Unix的思想的表现之一。本章将会学习这些工具和使用工具的具体实例,包括以下几方面:

(1)make命令及makefile文件

(2)源代码控制软件RCS和CVS

(3)写Manual说明页

(4)使用patch和tar分发软件

(5)开发环境

 

--------华丽的分隔符-----------

多个源文件的问题

当我们写小型程序时,许多开发者可以在修改代码后简单的重新编译他们的程序。但是,当开发大型项目时,这种方法就显现出来问题了。项目的修改-编译-测试周期变长了。即使是最耐心的开发者也难以忍受修改一个文件就要编译整个工程。

一个更加潜在的困难问题是建立了多个头文件,这些头文件包含在不同的源文件中。假设有a.h, b.h以及c.h三个头文件,有main.c 2.c和3.c三个C的源文件(实际项目中请不要使用这样的命名)。你可能会遇到以下的情景:

 

如果开发者改变了c.h文件,那么main.c以及2.c无需重新编译,这是因为它们都不依赖于c.h。但是3.c因为依靠于c.h所以就需要重新编译。另外,若b.h更改后忘记重新编译2.c文件,那么结果是程序的功能运行不正常。

make工具通过确定文件的更改从而确定有无需要重新编译,所以能解决上述问题。

注:make命令不止用来编译程序,还可以通过输入文件构造输出文件,其他应用包括文档处理(e.g. troff or TeX)。

 

 

----------------------华丽的分割线--------------------------------

make命令以及Makefiles

  虽然make命令有内嵌的智能,但是仍然不能完全编译您的程序。你必须提供一个文件告诉make命令如何构造您的程序。这个文件就成为makefile.

  makefile很多时候都和源代码文件在同一目录里,在任何时候你的电脑上都可以存在多个makefile。实际上,当项目很大时,你可以在项目的不同部分使用不同的makefile。

  make命令与makefile的结合为操作项目提供了强大的工具,不仅能够控制源代码的编译,也能用来写manual说明页以及安装程序到某个目录。

Makefile的语法

  makefile包含依赖关系以及规则关系。依赖关系根据源代码生成目标文件;规则关系描述了如何从依赖的文件建立目标文件。准确的说,target就是一个可执行文件。

  make命令读取makefile,决定如何输出目标文件,然后根据源文件的修改日期决定如何构建目标。通常,先建立中间文件,然后才建立目标文件。make命令使用Makefile决定输出目标文件的次序。

 

make命令的选项参数

make程序本身有些选项,最常用三种是:

1)-k,使make工具发现错误后不是立即停止,而是对错误之后的源代码文件继续编译。可以使用本选项一次性发现错误。  

2)-n,使make工具打印出它要如何编译,但不是真正的编译。

3)-f <filename>,用于指定make工具使用哪个makefile文件。如果不指定此选项,make标准版工具将会首先在当前目录下寻找叫做makefile的文件,若找不到就寻找Makefile文件。但是在大多数Linux系统中使用GNU版的Make工具,make会首先寻找GNUnakefile,然后是makefile,最后是Makefile。习惯上大多数程序员使用Makefile,这使makefile文件在以小写的文件名称按字典排序的目录里排在首位。建议不使用GNUmakefile,因为它只针对GNU版本实现。

 

通过设置参数告知make工具建立一个目标文件,通常是可执行文件。如果不这样做的话,make会建立在makefile文件里的第一个目标。许多程序员指定all为他们makefile的第一个目标,并且将其他的目标文件作为all的依赖文件。这种习惯使得在没指定目标的情况下makefile文件默认构造目标正确。建议采用这种技巧。

--------------------------------华丽的分割线------------------------------

依赖关系

依赖关系指定在最后的程序中每一个文件与源文件的关系,在本章的前面的例子中,需要指定最后的程序需要依赖于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。所以当main.c和a.h修改后就影响到main.o,main.c和a.h有一个修改后就需要重新编译main.c.

在makefile文件中,通过指定目标名称后加一个冒号,空格和制表符,然后用空格或制表符分割文件列表来建立目标文件,前面的例子的依赖关表如下:

这说明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目标,make简单的构造完makefile中的第一个目标就停下了。

 

--------------------------------华丽的分割线---------------------------------------------

规则关系

makefile的第二部分指明如何构造目标,在前几节的例子中,当make命令需要重建2.o时应当执行什么命令呢?也许简单使用gcc -c 2.c就已经足够了(make命令知道默认的规则),但是,当你需要指明一个include目录或是为了以后调试而加入调试符号又该如何办呢?通过在makefile文件中加入明确的规则就可以实现。

 

在此,需要提醒你makefile的一个奇怪和不幸的语法:空格符和制表符的差别。所有的规则所在的行都必须以tab制表符开始,空格不能开始新的一行。多个空格与制表符看起来没有什么差别,在Linux编程方面也没有很大的差别,但这会引起问题。makefile一行的末尾加入空格将导致make命令失败。但是这是历史遗留下的问题,而且有很多makefile试图去改变这个问题,所以务必要小心。幸运的是,make命令不工作是由于tab制表符丢失造成的。

 

试一试

大多数规则代表的简单命令都可以在命令行中敲入运行,作为例子,以下是你的第一个makefile:Makefile1

 

在上面的makefile中由于你未使用默认的名称:makefile或Makefile,所以使用-f 参数指定文件名。若果在没有源文件的目录中执行上述代码,你会得到如下信息:

$make -f Makefile1

make:*** No rule too make target 'main.c',needed by 'main.o'. Stop.

$

 

 

 

 (未完待续)

 

本人对翻译后的文字保留一切权利,转载请注明出处,有任何问题请email:shmtmc#163.com(将#改为@)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/naiveC/article/details/4360553

智能推荐

九、MySql数据库--关联查询(九)_二旬、的博客-程序员宅基地

一、关联查询(多表查询)1.1 笛卡尔乘积现象 交叉连接查询(不推荐。产生笛卡尔乘积现象:4 * 4=16,有些是重复记录) SELECT empName,deptName FROM employee,dept; 笛卡尔乘积现象: 假如employee有4条记录,dept有4条记录, 那么上面的sql查询结果,则为 4*4 条...

伸缩布局 lib-flexible自适应所有设备_给我一个div,我给你画个饼的博客-程序员宅基地

伸缩布局 lib-flexible自适应所有设备lib-flexible官方只能适配小于540分辨率的设备修改此处可适配所有function refreshRem(){ var width = docEl.getBoundingClientRect().width; if (width / dpr &gt; 540) { //width = 540*dpr; width = width * dpr;//这里的540 替换成width } var rem = width / 10; d

佳能ts9020墨盒不识别_感动常在!佳能ts9020打印机更换墨盒经验_weixin_39839541的博客-程序员宅基地

感动常在!佳能ts9020打印机更换墨盒经验2017-12-15 18:21:365点赞14收藏2评论很多人因为在张大妈这里推荐买了一台海淘打印机ts9020,本人也买了,曲折的海淘经历上一篇已经叙述,今天我给大家来说说墨盒的问题,算是给大家分享一点经验,做的不好,希望能帮到大家就是我的本意,如果能送点金币就更佳了,谢谢大家支持!首先我们看到这个原装墨盒很小,上面条形码位置还有一个很小的墨孔,可以...

前端学习——正则表达式_osmundZ-的博客-程序员宅基地

文章目录正则表达式使用test方法正则表达式使用test方法let testStr = "you are a genius";let testRegex = /are/;let hasAre = testRegex.test(testStr);//返回值:true

多晴转云h_多晴转云htxt百度云_伤的太深的博客-程序员宅基地

更新时间:2020-05-08 06:27:17一个大妈看到了不该看的东西,立马捂着眼睛道:“变态啊!”她这么一出声,大家都反应过来,露出气愤又鄙夷的神情,纷纷对着男人一顿指指点点。“难怪人家狗咬你,活该!”“像你这种败类,就应该被咬死!”男人见状不妙,立马慌慌张张的挤到另一边,下一站就急忙出去了。苏瓷跟帮忙的人们道了谢。大家摆手道:“小姑娘不用这么客气,下次要是再遇上这种人,绝对不能忍着,知道了...

src=“[object Module]“ 的原因及解决方案_七月pro的博客-程序员宅基地

使用webpack4构建的项目,出现 src="[object Module]" 的原因及解决方案。Vue官方文档中说了vue-loader的基本原理,他会将Vue模板中的 转为下面这段JS代码:createElement('img', { attrs: { src: require('../image.png') // require()是CommonJS模块语法 }})对于图像我们在Webpack中一般使用 url-loader 来处理{ test: /\.(

随便推点

wxpython界面代码和逻辑代码分离_使用wxPython打造印象笔记(17)笔记排序和重构管理笔记本功能..._weixin_39675679的博客-程序员宅基地

这篇文章我们来实现笔记列表的排序和笔记本编辑删除功能,最终实现效果如下:笔记排序笔记本重命名(编辑)删除笔记本笔记排序功能用户从排序菜单中点击一个排序选项之后,笔记列表将清空,然后列表中的笔记执行排序操作,最后笔记列表会加载已排序的笔记。需要注意的地方:如果排序前笔记A高亮(预览面板的背景色加深),那么排序之后,笔记A依然需要高亮,并且文本编辑器不发生变化用户选择的排序选项需要记录下来,如果用户选...

html5替代wpf,WPF仿百度Echarts人口迁移图 - 普通的地球人_wewooseo的博客-程序员宅基地

关于大名鼎鼎的百度Echarts我就不多说了 不了解的朋友直接看官方的例子吧前阵子我加入了一个WPF的技术交流群 次demo的完成 首先得感谢群里的上进有为青年 十年 他总能发一些效果 让人看了就忍不住想想自己有没有思路实现 甚至想写写看 于是就有了此demo这个demo写了个什么东西 我先上个图吧 让大家有个直观的印象 录gif的关系 看起来可能有点卡我没用过百度Echart 所以可能和百度Ec...

linux可以运行宏的excel吗,C#执行Excel宏模版的方法_Gakki我老婆的博客-程序员宅基地

C#执行Excel宏模版的方法在项目中如果涉及到用Excel开发的报表模版来导出报表数据的话,一般都是在Excel报表中使用VBA做成宏来进行调用。即先使用Excel自带的VBA开发好报表模版,然后再将模版程序放在固定目录下,在管理软件中对这些报表模版进行调用。这样就不需要使用其它报表工具来进行开发了,因为Excel功能比较强大,一般的应用的报表用它来开发绰绰有余了。而且这样开发的成本也很低,不需...

xp系统修改服务器时间格式,WindowsXP系统中设置时间、日期格式_weixin_39735247的博客-程序员宅基地

《WindowsXP系统中设置时间、日期格式》由会员分享,可在线阅读,更多相关《WindowsXP系统中设置时间、日期格式(3页珍藏版)》请在人人文库网上搜索。1、Windows XP系统中设置时间、日期格式第一步:点击“开始”、再点击“控制面板”;Adminis tetoTTn ter netInternet Explorer电子邮件Outlook Expr&amp;EEMicrosoft Wo...

flask mysql保存图片,如何将多幅图像保存到Flask数据库中?_麓鸯的博客-程序员宅基地

我想上传一个以上的图片到数据库,我已经创建的形式,并得到所有图片上传完美。在在我的视图中,我创建了一个list来包含所有图像,如果我将数据库中的列表保存在images列中,则会得到一个字典,而不是一个列表,它一个接一个包含所有图像,如下所示:{u'123.jpg',u'123.jpg',u'123.jpg'}问题在于,如果我想通过索引获取它们,那么获取的是字母而不是值。在另一种方法是,我创建了另一...

c++ 准确计时_C++下四种常用的程序运行时间的计时方法总结_weixin_39570505的博客-程序员宅基地

记录下当前时间start,调用程序fun(),再记录一下时间end。前后时间一减(start-end)就得到程序的运行时间了。首先介绍最常用的,但两种精度不是很高(&gt;=10ms)的方法:clock()和GetTickCount()一、clock()C系统调用方法,所需头文件ctime/time.h,即windows和linux都可以使用。1、clock()返回类型为clock_t类型2、cl...

推荐文章

热门文章

相关标签