Linux下应用程序开发基础.docx
《Linux下应用程序开发基础.docx》由会员分享,可在线阅读,更多相关《Linux下应用程序开发基础.docx(44页珍藏版)》请在冰豆网上搜索。
![Linux下应用程序开发基础.docx](https://file1.bdocx.com/fileroot1/2023-2/24/37909f53-5115-472c-a338-74c2ce8c1e5b/37909f53-5115-472c-a338-74c2ce8c1e5b1.gif)
Linux下应用程序开发基础
第三章Linux下应用程序开发基础
在Linux系统下进行应用程序开发,必须先熟悉GNU/Linux系统下的开发工具的使用。
在本章中,我们主要介绍全屏编辑器vi(VIM)、集成开发工具KDevelop、交叉编译工具GNUGCC套件的功能及使用。
另外,为了提升应用程序的可读性和可维护性,在第4小节专门就嵌入式应用程序的编程风格进行简单描述。
3.1vi编辑器
3.1.1vi简介
vi是Linux系统最常用的全屏编辑器,所有的Linux机器都提供该编辑器,而Linux里提供的是vi的加强版——VIM,但同vi是完全兼容的。
vi的原意是“visualinterface”,即可视编辑器,用户键入的内容会立即被显示出来,而且其强大的编辑功能可以同任何一种最新的编辑器相媲美。
它在Linux上的地位就仿佛Edit程序在DOS上一样。
它可以执行输出、删除、查找、替换、块操作等众多文本操作,而且用户可以根据需要对其进行定制,这是其他编辑程序所没有的。
vi不是一个排版程序,不象Word或WPS那样可以对字体、格式、段落等其他属性进行编排,它只是一个文本编辑程序。
3.1.2vi基本操作模式
vi有三种基本操作模式,它们是:
●插入模式:
插入模式即为文本编辑模式。
这个模式用于输入文本或程序,输入字母i,即进入插入模式,按ESC键返回到命令模式。
●可视
◆命令模式:
一般当进入vi时,会首先进入可视命令模式,这是vi的启动默认模式,这种模式用于输入操作命令。
●冒号命令模式:
在冒号命令模式下,所有命令都要以“:
”开始,所输入的字符均作为命令来处理。
3.1.3vi的进入和退出
在Linux系统的终端命令行模式下键入命令vi,后面跟上想要编辑(或者建立)的文件名,vi可以自动载入所要编辑的文件或是开启一个新文件。
如果想用Linux桌面上的VIM编辑器,可以从Linux桌面上点击主菜单→编程→VIM,进入VIM启动界面,然后可通过选择上方的菜单来进行操作。
vi的退出,可以在冒号命令行模式下使用命令“:
wq”或者“:
q!
”,前者的功能是写文件并从vi中退出,后者的功能是从vi中退出,但不保存所作的修改(注意冒号)。
VIM的退出也可通过选择编辑器上方的菜单来完成。
3.1.4vi的命令
(1)光标的移动
用户除了通过按键盘的上、下、左、右箭头键来移动光标,还可以利用vi提供的字母键h(左移)j(下移)k(上移)l(右移)来完成光标的移动。
(2)删除和替换类命令
x—删除光标所在位置的字符。
dw—删除光标处的单词。
d$—从当前光标删除到行末。
dd—删除光标所在行。
r—输入r和一个字符替换光标所在位置的字符。
u—恢复前一次所做的操作。
(3)更改命令
cw—改变一个单字/单词的部分或者全部。
更改类指令可以使用同删除类命令所使用的对象参数。
(4)置入命令
p—将最后一次删除的内容置入光标之后。
(5)配对括号的查找
%—可以查找配对的括号)、]、}。
在程序调试时,这个功能用来查找不配对的括号是很有用的。
(6)提取和合并文件
:
r文件名—向当前文件中插入另外文件的内容,将文件提取进来。
(7)打开类命令
输入小写的o可以在光标下方打开新的一行并将光标置于新开的行首,进入插入模式。
输入大写的O可以在光标上方打开新的一行并将光标置于新开的行首,进入插入模式。
(8)查找字符串
在命令行键入字符“/”,后面加上要搜索的字符串,然后按回车键,编辑程序将执行正向搜索(从光标所在的位置向文件末尾方向),并在找到指定字符串后,将光标停在该字符串的开头;键入n命令可以继续执行搜索,找出这一字符串下次出现的位置,用字符“?
”取代“/”,可以实现反向搜索(从光标所在的位置向文件开头方向)。
(9)存盘/退出命令
:
w—保存到文件,存盘不退出。
:
q!
—放弃任何改动而退出,即强行退出。
:
w!
—对于只读文件强行存档。
:
wq—存档并退出vi。
:
#,#w文件名—保存文件的部分内容。
这里的#,#就是顶端行号和底端行号。
(10)在线帮助命令
VIM拥有一个细致全面的在线帮助系统。
要启动该帮助系统,请选择如下三种方法之一:
◆按下键(如果键盘上有的话)
◆按下键(如果键盘上有的话)
◆输入:
help<回车>
输入:
q<回车>可以关闭帮助窗口。
如果要在vi执行期间,转到shell执行,可使用(!
)将执行系统命令。
例如,在vi的命令状态,列出当前目录内容,可以输入:
:
!
ls
注意:
在文本编辑模式下,不能输入命令,必须先按下Esc键,返回命令模式。
假如用户不知身处何态,也可以按下Esc键,这时不管处于何态,都会返回命令模式。
3.1.5VIM新增功能
VIM意为VIImproved,与vi99%向下兼容,而且VIM提供了许多vi不具备的功能,内置了诸多函数,因此建议大家熟悉了vi的基本操作以后,不妨转向VIM。
选择一款好的编辑器是进行高效编程的第一步,VIM以其强大的功能和无穷魅力将提升在Linux下编程的效率。
下面介绍VIM新增功能及特点。
●VIM支持语法制导和自动缩进。
VIM会根据文件的后缀名,如:
*.c、*.cpp、*.cc,等,自动设置语法制导(SyntaxHighlighting)。
C/C++中的一些保留字,如:
if、for、include,等等,就会有不同的颜色,这样就会减少程序员犯错的可能,阅读程序的时候相对来说也轻松很多。
VIM也支持根据GNU的风格自动缩进,这样程序员编写出来的代码就更易阅读,而且也有利于培养好的编程风格。
●VIM有一套优秀的语法高亮机制。
利用这一机制可帮你找到程序中存在的错误。
语法高亮用特殊的颜色来显示注释,你可以快速发现哪些部分应该是一个注释.但是并没有被语法高亮指出来。
对程序员来说,忘记注释的结束标记*/是很正常的事,这在只有黑白两色的文本中可不是一件省油的事。
没有正确匹配的括号也可被语法高亮指出。
一个没有被正确匹对的括号"}"会被一个亮红色的背景特别指出。
你可以使用"%"命令看一看它应该跟谁匹配,然后在正确的位置补上一个。
●VIM提供了快速定位的功能。
如果你找到一个变量并且想找出这个变量还在其它哪些地方出现,可以使用“*”命令,它查找下一个匹配的目标。
如果你设置了incsearch选项,VIM将会以反白显示出第一个被找出的匹配。
如果你设置了hlsearch选项,Vim将会高亮显示所有查找到的匹配,这种策略可以让你对要查找的内容有一个概括的了解,如果你在程序代码中使用这一功能,它能显示出所有引用某个变量的地方。
●VIM提供了一个补全机制。
当输入一个比较长的函数名或变量名时,只要输入前几个字符,然后通过按下CTRL-N键,VIM的补全机制就会补全剩下的字符。
这个功能不仅节省了你输入程序的时间,还减少了手工输入代码时出错的机会。
●使用tags文件快速跳转到函数定义处。
在写C程序时,经常要花时间找到一个函数的定义,在上面提到用“*”命令可以查找这个函数名都在哪些地方出现过,但在你到达真正的目标之前,可能还有符合你的查找条件的很多个匹配(如注释中出现的该函数)干扰你。
VIM提供了一个Ctags程序,可以帮助编程人员很容易的浏览源代码。
用下面的命令可以在源代码的根目录下创建“tags”文件:
[/home/brimmer/scr]#ctags-R
“-R表示递归创建,也就包括源代码根目录下的所有子目录下的源程序。
“tags”文件中包括用#define定义的宏、枚举型变量的值、函数的定义、名字空间、类型定义、变量、类等对象的列表。
VIM用这个“tags”文件来定位那些做了标记的对象。
定位这些对象的方法如下:
1用命令行。
在运行VIM的时候加上“-t”参数,例如:
vim-tfoo_bar
这个命令将打开定义“foo_bar”(变量或函数或其它)的文件,并把光标定位到这行。
2在VIM编辑器内用“:
ta”命令,例如:
:
tafoo_bar
3最方便的方法是把光标移到变量名或函数名上,然后按下“Ctrl-]”,用“Ctrl-o”返回原来的地方。
注意:
运行VIM的时候,必须在“tags”文件所在的目录下运行。
否则,运行VIM的时候还要用“:
settags=”命令指出“tags”文件的路径,这样VIM才能找到“tags“文件。
●VIM提供了它自己的“:
make”命令。
在VIM编辑器的环境下用“:
make”命令就可以编译你的程序项目,捕获编译的错误/警告并允许你直接跳转到引起这一错误/警告的程序行上去。
(前提是在当前目录下有Makefile文件。
)运行完“:
make”之后,如果程序中有错误,就会显示出来,这时候,光标会自动指向第一个出现错误的地方,而且你还可以看到错误提示。
然后,你就可以改正错误。
3.2集成开发工具KDevelop
3.2.1Kdevelop的简介
Kdevelop是一套功能强大的集成开发环境,其整合了开发程序所需的编译器、连接器、除错工具、版本控制工具等,可以用Kdevelop快速地建立各式各样的应用程序。
Kdevelop基于X-Window系统,界面友好,程序员在一个环境中就可以完成分析、设计、编译、调试、运行等整个流程,尽管KDevelop源于KDE/Qt,但并不局限于KDE/Qt,它同时还支持GNOME/gtk+、传统字符界面C/C++开发,KDevelop为快速地开发C/C++应用程序提供强有力的开发工具。
3.2.2启动Kdevelop
如果是第一次使用Kdevelop,Kdevelop会先启动“Kdevelop设置”,进行Kdevelop的环境设定,共需要完成9个步骤的设置工作,如图3-1所示。
图3-1图3-1Kdevelop设置图3-2选择语法高亮风格
单击“Kdevelop设置欢迎画面对话框中的【下一步】按钮开始进行Kdevelop的设定。
Kdevelop设置的第二项设定为“选择语法高亮风格”,这里选择缺省的“Kdevelop2.0风格”,如图3-2所示。
选择喜欢的语法高亮表示风格后,单击【下一步】按钮进入“用户交换界面模式”的选择窗口,如图3-3所示。
同样选择好用户交换界面模式后,单击【下一步】按钮进入“Kdevelop中所使用的工具检测窗口”,如图3-4所示。
图3-3选择用户交换界面图3-4工具检测
图3-2
图3-4Kdevelop所使用的工具检测窗口
单击“工具程序检测窗口”对话框中的【下一步】按钮,进行下一个步骤。
下一个步骤为“寻找Qt文档”,并设定文件路径,一般而言这个步骤应该会成功完成。
Qt文档查找界面如图3-5所示。
图3-5Qt文档查找图3-6安装过程成功完成窗口
图3-5
单击“寻找Qt文档”对话框之中的【下一步】按钮,进入下一个步骤。
下一个步骤为“寻找KDE程序库文件”,同样,一般而言这个步骤也应该会成功完成。
再缺省完成两步以Kdevelop设置将显示“安装过程成功完成”的对话框,如图3-6所示,此为Kdevelop设置的最后步骤,单击【下一步】按钮,稍待一会Kdevelop便会启动。
3.2.33.2.3创建一个新项目
在Kdevelop中开发C程序,需要用创建项目的方式进行。
请执行“项目/新建”命令,打开应用程序向导对话框,创建过程如图3-7所示。
图3-7创建新项目
选择要创建程序的种类,这里选择C程序,然后单击【后一页】按钮进行下一步骤。
下一个步骤为关于项目信息的设定,如图3-8所示,在此输入项目的名称、目录、版本号码、作者姓名、以及作者电子邮件地址,后两项可以不填。
可把“生成源文件和头文件”前的勾去掉,(如不去掉勾,系统会自动生成一些源代码),单击【创建】按钮,等屏幕出现“Ready”信息后,单击“退出”,项目便生成了。
图3-8输入项目信息
3.2.4输入源程序
创建项目后,下边要输入源程序了,选择文件菜单中的“新建”命令,新建一个“C/C++程序”,如图3-9所示,或者在Kdevelop窗口的左边选择源程序,这时系统自动按照其选定的文件头摸板生成一个空文件,这时可开始输入程序,例如,输入如图3-10所示程序:
图3-9新建C/C++文件
图3-10输入源程序
3.2.5项目的编译与执行
写好程序后,先在“建立”菜单中,点击“autoconf和automake(A)”,然后,执行“建立/编译”命令进行程序的编译,如果程序没有出错,经过一段时间的编译,将看到Kdevelop下方的信息框之中显示编译成功的信息,如上图所示。
接着便可以执行应用程序了。
选择“建立/执行”命令进行程序的连接,或者点击工具栏中的“执行”按钮,若没有发生问题,就会在另一个窗口中看到程序的执行结果,如上例终端中就会输出“Helloworld!
”这句话,如图3-11所示。
图3-11程序运行成功界面
3.3交叉编译工具GNUGCC
3.3.1GNUGCC简介
GUN编译器集合(GCC)是一个“免费”的C/C++工具链,它有力地支持了Linux系统的发展,由于它被看作许多嵌入式处理器的一个交叉编译器,所以在嵌入式应用程序开发中是一个非常流行的交叉编译工具,它包括C/C++交叉编译器arm-elf-gcc、汇编器arm-elf-as、连接器arm-elf-ld、库管理器arm-elf-ar、工程管理器make、调试工具gdb和其他一些实用程序。
它的基本功能包括如下几点:
1.输出预处理后的C/C++源程序;
2.输出C/C++源程序的汇编代码;
3.输出二进制目标文件;
4.生成静态库;
5.生成可执行程序;
6.转换文件格式。
在这里我们还要理清Linux软件开发中的一些基本概念。
●编辑器与编译器的概念:
编辑器是输入程序代码的裁体。
Linux提供了几款编辑器,如vi(VIM),还有KDevelop等。
而编译器则是将源程序转换成机器可识别的二进制代码的工具。
●交叉编译器的基本概念:
交叉编译器本身是运行在host(宿主机)上,而交叉编译器所生成的代码则运行在target(目标机)上。
●Linux操作系统之上编程与操作系统之下编程的区别:
在Linux操作系统之上编程,例如,有一个C语言写的源文件hello.c,要对它进行编译,可用gcc编译器,命令行如下:
#gcc–ohello.ohello.c
其中gcc是Linux编译器的名字,-o选项指定输出文件名。
到这里,程序与嵌入式系统目标机没有任何关联,所以说这是在操作系统之上编程。
而在操作系统之下编程,一定要与目标机相关联,即所编的程序经过编译连接以后产生的可执行文件要下载到目标机上运行,这时所用的编译器应该是交叉编译器arm-elf-gcc,也可说是目标编译器。
北京博创公司的UP-NETARM3000实验平台使用µclinu的交叉编译器是arm-µclibc-gcc,它的命令格式、命令选项及命令的使用同arm-elf-gcc是一样的。
µclibc是µclinux提供的经过裁减的操作系统的库,应用程序很大一部分是在和库函数打交道。
在目标板使用操作系统的开发模式下,交叉编译环境中还需要对应该操作系统的库。
开发应用程序可以先在宿主机上调通,然后用交叉编译器为目标板重新编译一遍,这样做是因为宿主机是Linux而目标板上跑的是µclinux,两个操作系统提供的应用程序接口几乎是一样的,所以程序几乎不用修改。
3.3.2C/C++交叉编译器arm-elf-gcc
arm-elf-gcc是编译的前端程序,它通过调用其他程序来实现将程序源文件编译成目标文件。
编译时它首先调用预处理程序(cpp)对输入的源程序进行处理,然后调用ccl将预处理后的程序编译成汇编代码,最后由arm-elf-gcc将汇编代码编译成目标代码。
arm-elf-gcc具有丰富的命令选项,控制编译的各个阶段,满足用户的各种编译需求。
1.命令格式
arm-elf-gcc[options]file…
在命令arm-elf-gcc后面可跟一个或多个选项,选项之间用空格隔开,然后跟一个或多个目标文件。
例如,将hello.c编译成目标文件hello.o并且生成调试信息:
arm-elf-gcc–g–c–ohello.ohello.c
其中:
-g选项表示在文件中产生调试信息;-c选项指定将输入的源文件编译成目标文件;-o选项指定输出文件名。
2.命令选项列表
(1)输出控制选项如下:
-c:
将输入的源文件编译成目标文件;
-S:
将C/C++文件生成汇编文件;
-ofile:
将输出内容存于文件file;
-pipe:
在编译的不同阶段之间采用管道通信方式;
-v:
打印出编译过程中执行的命令;
-xlanguage:
说明文件的输入类型为language。
(2)C语言选项如下:
-ansi:
支持所有ANSIC程序。
(3)警告选项如下:
-w:
关闭所有警告;
-Wall:
打开所有警告;
-Wimplicit:
如果有隐含申明,显示警告信息;
-Wno-implicit:
不显示对隐含申明的警告。
(4)调试选项如下:
-g:
该选项
在文件中产生调试信息以便调试程序(调试信息的文件格式有stabs、COFF、XCOFF、DWARF)。
(5)优化选项如下:
-O0:
不优化;
-O1:
一级优化;
-O2:
二级优化;
-O3:
三级优化。
(6)预处理选项如下:
-E:
运行C的预处理器;
-C:
在运用-E进行预处理时不去掉注释;
-Dmacro:
定义宏macro为1;
-Dmacro=defn:
定义宏macro为defn。
(7)汇编选项如下:
-Wa,option:
将选项option传递给汇编器。
(8)搜索路径选项如下:
-Idir:
设置搜索路径为dir;
-I-:
指定只对#include“file”有效的头文件搜索目录。
3.源文件类型的识别
arm-elf-gcc能够自动根据文件名后缀识别文件类型。
文件名后缀和文件类型的对应关系如下:
*.c:
C源文件;
*.i:
经过预处理后的C源文件;
*.h:
C头文件;
*.ii:
经过预处理后的C++源文件;
*.cc:
C++源文件;
*.cxx:
C++源文件;
*.cpp:
C++源文件;
*.C:
C++源文件;
*.s:
不需要预处理的汇编文件;
*.S:
需要预处理的汇编文件。
此外,用户可通过-xlanguage说明文件的输入类型,此时可以不用以上的后缀规则。
例如:
-xlanguage
其中的language可为以下参数:
c:
C源文件;
c++:
C++源文件;
c-header:
C头文件;
cpp-output:
经过预处理后的C源文件;
c++-cpp-output:
经过预处理后的C++源文件;
assembler:
不需要预处理的汇编文件;
assembler-with-cpp:
需要预处理的汇编文件。
例如,编译一个不需要预处理的C程序:
arm-elf-gcc–c–g–xcpp-outputhello.c
-xnone
如果-x后面未跟任何参数,则按照文件的后缀名做相应处理。
4.命令的使用
(1)输出文件名的指定
-ofile。
将输出内容存于文件file,仅适用于只有一个输出文件时。
例如,将hello.c编译成汇编程序并存放于文件hello.txt:
arm-elf-gcc–S–ohello.txthello.c
(2)目标文件的生成
-c。
将输入的源文件编译成目标文件。
例如,将hello.c编译成hello.o:
arm-elf-gcc–c–ohello.ohello.c
(3)将C/C++文件生成汇编文件
-S。
将C/C++文件生成汇编文件。
例如,将hello.c编译生成汇编文件hello.s:
arm-elf-gcc–S–ohello.shello.c
(4)预处理文件的生成
-E。
只对源文件进行预处理并且默认输出到标准输出。
例如,对hello.c进行预处理并将结果输出到屏幕:
arm-elf-gcc–Ehello.c
(5)设置头文件搜索路径
头文件的引用有两种形式:
一种是#include“filename”,另一种是#include。
前一种形式的路径搜索顺序是:
当前目录、指定的搜索路径;后一种形式只搜索指定路径。
①-Idir。
将目录dir添加到头文件搜索目录列表的第一项。
通过此选项可以使用户头文件先于系统头文件被搜索到。
如果同时用-I选项添加几个目录,目录被搜索时的优先级顺序为从左到右。
例如,编译hello.c,在当前目录和/µClinux目录中搜索hello.c所包含的头文件:
arm-elf-gcc–I./-I/µClinux–chello.c
②-I-。
-I-以前用-I指定的头文件搜索目录只对#include“file”有效,对#include无效;-I-以后指定的头文件搜索目录对以上两种形式的头文件都有效。
此外,-I-会禁止对当前目录的隐含搜索,不过用户可以通过使用“-I.”使能对当前目录的搜索。
(6)控制警告产生
用户可以使用以-W开头的不同选项对特定警告进行设定。
例如,如有隐含申明,显示警告信息:
arm-elf-gcc–c-Wimplicithello.c
(7)实现优化
优化的主要目的是使编译生成的代码的尺寸更小、运行速度更快,但是在编译过程中随着优化级别的升高,编译器会相应消耗更多时间和内存,而且优化生成代码的执行顺序和源代码有一定出入,因此优化选项更多地用于生成固化代码,而不用于生成调试代码。
①-O1。
可以部分减小代码尺寸,对运行速度有一定的提高。
较多地使用了寄存器变量,提高指令的并行度。
②-O2。
除了解循环、函数插装和静态变量优化,几乎包含arm-elf-gcc所有优化选项。
一般在生成固化代码时使用该选项较为适宜。
③-O3。
包含-O2的所有优化,并且还包含了解循环、函数插装和静态变量优化。
通常情况下,该级优化生成的代码执行速度最快,但是代码尺寸比-O2大一些。
(8)在命令行定义宏
☉-Dmacro:
定义宏macro为1。
☉-Dmacro=defn:
定义宏macro为defn。
例如,编译hello.c并且预定义宏RUN_CACHE值为1的命令行如下:
arm-elf-gcc–c–DRUN_CACHEhello.c
编译hello.c并且预定义宏RUN_CACHE值为0的命令行如下:
arm-elf-gcc–c–DRUN_CACHE=0hello.c
3.3.3交叉连接器arm-elf-ld
arm-elf-ld根据链接定位文件Linkcmds中代码段、数据段、BBS段和堆栈段等定位信息,将可重定位的目标模块链接成一个单一的、绝对定位的目标程序,该目标程序是ELF格式,并且可以包含调试信息。
arm-elf-ld可以输出一个内存映像文件,该文件显示所有目标模块、段和符号的绝对定位地址,它也产生目标模块对全局符号引用的交叉参考列表。
1.命令格式
arm-elf-ld的命令格式如下:
arm-elf-ld[option]file…
命令行后跟选项和可重定位的目标文件名。
例如,若链接的输入文件为ming