版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux开发基础础原仓仓周周第二二章章Linux程程序序设设计计基基础础——C环环境境Linux编编程程概概述述文本本编编辑辑器器viLinux下下函函数数库库GCC及及其其使使用用调试试工工具具gdbGNUmake和和makefileLinux编编程程概概述述Linux软软件件开开发发一一直直在在Internet环环境境下下讲讲行行。。这这个个环环境境是是全全球球性性的的,,编编程程人人员员来来自自世世界界各各地地。。只只要要能能够够访访问问Web站站点点,,就就可可以以启启动动一一个个以以Linux为为基基础础的的软软件件项项目目。。Linux开开发发工工作作经经常常是是在在Linux用用户户决决定定共共同同完完成成一一个个项项目目时时开开始始的的。。当当开开发发工工作作完完成成后后,,该该软软件件就就被被放放到到Internet站站点点上上,,任任何何用用户户都都可可以以访访问问和和下下载载它它。。由由于于这这个个活活跃跃的的开开发发环环境境,,新新的的以以Linux为为基基础础的的软软件件功功能能日日益益强强大大,,而而且且呈呈现现爆爆炸炸式式的的增增长长态态势势。。大多多数数Linux软软件件是是经经过过自自由由软软件件基基金金会会((FreeSoftwareFoundation))提提供供的的GNU((GNU即即GNU’’snotUNIX))公公开开认认证证授授权权的的,,因因而而通通常常被被称称作作GNU软软件件。。GNU软软件件免免费费提提供供给给用用户户使使用用,,并并被被证证明明是是非非常常可可靠靠和和高高效效的的。。许许多多流流行行的的Linux实实用用程程序序如如C编编译译器器、、shell和和编编辑辑器器都都是是GNU软软件件应应用用程程序序。。Linux程程序需要首先先转化为低级级机器语言即即所谓的二进进制代码以后后,才能被操操作系统执行行。例如编程时,,先用普通的的编程语言生生成一系列指指令,这些指指令可被翻译译为适当的可可执行应用程程序的二进制制代码。这个个翻译过程可可由解释器一一步步来完成成,或者也可可以立即由编编译器明确地地完成。shell编编程语言如BASH、TCSH、GAWK、Perl、Tcl和Tk都利用自己己的解释器。。用这些语言言编制的程序序尽管是应用用程序文件,,但可以直接接运行。编译译器则不同,,它将生成一一个独立的二二进制代码文文件然后才可可以运行。Linux编编程风格GNU风格Linux内内核编程风风格GNU风格(1/2)函数返回类型型说明和函数数名分两行放放置,函数起起始字符和函函数开头左花花括号放到最最左边。尽量不要让两两个不同优先先级的操作符符出现在相同同的对齐方式式中,应该附附加额外的括括号使得代码码缩进可以表表示出嵌套。。按照如下方式式排版do-while语句:do{}while()每个程序都应应该以一段简简短的说明其其功能的注释释开头。请为每个函数数书写注释,,说明函数是是做什么的,,需要哪些入入口参数,参参数可能值的的含义和用途途。如果用了了非常见的、、非标准的东东西,或者可可能导致函数数不能工作的的任何可能的的值,应该进进行特殊说明明。如果存在在重要的返回回值,也需要要说明。不要声明多个个变量时跨行行,每一行都都以一个新的的声明开头。。GNU风格(2/2)当一个if中中嵌套了另一一个if-else时,,应用花括号号把if-else括起起来。要在同一个声声明中同时说说明结构标识识和变量或者者结构标识和和类型定义(typedef)。先先定义变量,,再使用。尽量避免在if的条件中中进行赋值。。请在名字中使使用下划线以以分割单词,,尽量使用用于表明一个命令行选项是否给出的变量应该在选项含义的说明之后,而不是选项字符之后被命名。Linux内内核编程风风格Linux内内核缩进风格格是8个字符符。Linux内内核风格采用用K&R标准准,将开始的的大括号放在在一行的最后后,而将结束束的大括号放放在一行的第第一位。命名尽量简洁洁。不应该使用诸诸如ThisVariableIsATemporaryCounter之类的的名字。应该该命名为tmp,这样容容易书写,也也不难理解。。命名全局变量量,应该用描描述性命名方方式,例如应应该命名“count_active_users()””,而不是““cntusr()”。。本地变量应该该避免过长函数最好短小精悍,一般来说不要让函数的参数多于10个,否则应该尝试分解这个过于复杂的函数。通常情况,注释说明代码的功能,而不是其实现原理。避免把注释插到函数体内,而写到函数前面,说明其功能,如果这个函数的确很复杂,其中需要有部分注释,可以写些简短的注释来说明那些重要的部分,但是不能过多。文本编辑器vivi的模式vi的进入命令模式插入模式末行模式vi的模式CommandMode(这是执行vi后的缺省模式此时键盘输入当作命令命令有大小写之区分InputMode(插入模式)使用a、i、o、c、r、s
进入插入模式用户输入的任何字符都被vi当做文件内容保存起来,并将其显示在屏幕上按下ESC键即可回到CommandModevi的模式LastMode(末行模式)在CommandLine按下:即即可进入该模式用来进行保存文文件、打开文档或环境的设定命令有大小写之分vi的进入和和内容输入进入:vi文件件名输入文件内容容((进入插插入模式)新增(append)
a从从光标所在位位置后面开始始新增内容A从光标所所在行最后面面的地方开始始新增内容。。插入入(insert)i从从光光标标所所在在位位置置前前面面开开始始插插入入内内容容I从从光光标标所所在在行行的的第第一一个个非非空空白白字字符符前前面面开开始始插插入入资资料料。。开始始(open)o在在光光标标所所在在行行下下新新增增一一行行并并进进入入输输入入模模式式。。O在在光光标标所所在在行行上上新新增增一一行行并并进进入入输输入入模模式式。。(命命令令模模式式))命令令模模式式1、、光光标标的的移移动动h左左移移一一个个字字符符l右右移移一一个个字字符符j下下移移一一行行k上上移移一一行行w,W跳跳至至后后一一个个字字的的开开头头(W忽忽略略标标点点)b,B跳跳至至前前一一个个字字的的开开头头((B忽忽略略标标点点))e移移动动到到后后一一个个字字的的末末尾尾^至至本本行行第第一一个个非非空空字字符符$至至行行尾(光标所在位置到该句子的第一个字母}光标所在位置到该段落的最后一个字母
{光标所在位置到该段落的第一个字母命令模模式1、光光标的的移动动(续续)nH将将光标标移到到屏幕幕的第第n行行nL将将光标标移到到屏幕幕的倒倒数第第n行行CTRL-d向向下下半页页CTRL-f向向下下一页页CTRL-u向向上上半页页CTRL-b向向上上一页页n-减减号移移动到到上一一行的的第一一个非非空白白字n+加号移动到下一行的第一个非空白字符,前面加上数字可以指定移动到以下n行命令模模式2、删删除x删删除除光标标所在在字符符X删删除光光标前前面的的字符符s删删除光光标所所在字字符,,并进进入输输入模模式S删删除除光标标所在在的行行,并并进入入输入入模式式dd删删除除光标标所在在的行行D从从光光标位位置开开始删删除到到行尾尾d与光光标移移动命命令的的组合合命令模模式3、修修改r修修改改光标标所在在字符符,r后后接着着要修修改的的字符符。如如,rc可可以以用字字符““c””替换换光标标所指指向的的当前前字符符R进进入入替换换状态态,新新增内内容会会覆盖盖原先先内容容,直直到按按[ESC]回回到命命令模模式下下为止止cc修修改光光标所所在行行C修修改从从光标标位置置到该该行末末尾的的内容容c与与光标标移动动命令令的组组合命令模模式4、复复制和和移动动yy复复制当当前行行到内内存缓缓冲区区nyy复复制制n行行内容容到内内存缓缓冲区区y与光光标移移动的的组合合p将将缓冲冲区的的内容容粘贴贴到光光标的的后面面P将将缓冲冲区的的内容容粘贴另:在末行模式下实现移动:n1,n2mn3:把n1到n2行内容搬到第n3行后5、搜搜索字字符串串/pattern移移至下下一个个包含含pattern的的行?pattern移移至至上一一个包包含pattern的行行/往往下重重复查查找?往往上上重复复查找找n在在同同一方方向重重复查查找N在在相反反方向向重复复查找找/pattern/+n移移至下下一个个pattern所所在行行后的的第?pattern?-n移至上一个Pattern所在行前的第n行
6、其他
u撤销前一条命令的结果*.$^[]{}\/包含在查找找字符串中中,要用转转义字符(\)命令模式末行模式1、文件的的保存和退退出:w保存:q退出:w!强制保存:q!强制退出:wq保存退出:wq!强制保存退退出末行模式2、字符串串的替换:s/str1/str2/用字字符串str2替替换行中中首次出现现的字符串串str1:s/str1/str2/g用用字符串str2替换行行中所有出出现的字符符串str1:.,$s/str1/str2/g用用字符串str2替换正正文当前行行到末尾所所有出现的的字符串str1:1,$s/str1/str2/g用用字符串str2替换正正文中所有有出现的字字符串str1:g/str1/s//str2/g功功能同上末行模式其他::n将将光标移到到第n行行编辑多个文文件vifile:n编辑下一个文件:efilename编辑指定文件Linux下函数库库(1/3)一个“程序序函数库””就是一个个文件包含含了一些编编译好的代代码和数据据,这些编编译好的代代码和数据据可以在事事后供其静态函数库(staticlibraries):是一个普通的目标文件的集合,一般用“.a”作为文件的后缀。静态函数库和共享函数库相比有很多的缺点,占用内存空间多。但使用ELF格式的静态库函数生成的代码可以比使用共享函数库的程序运行速度上快一些。可以用ar这个程序来创建一个静态函数库文件,或者往一个已经存在地静态函数库文件添加新的目标代码。例如,把file1.o和file2.o加入到my_library.a这个函数库文件:
arrcsmy_library.afile1.ofile2.o然后运行ranlib,以给库加入一些索引信息Linux下函数库库(2/3)共享函数库库(sharedlibraries):当当一个可执执行程序在在启动的时时候被加载载的函数。。每个共享享函数库都都有个特殊殊的名字,,称作“soname”。soname名字命命名必须以以“lib”作为前前缀,然后后是函数库库的名字,,然后是““.so””,最后是是版本号信信息。优点:多进进程使用同同一函数库库;修改函函数库不需需重新连编编。安装一个新新版本的函函数库的时时候,要先先将这些函函数库文gcc-fPIC-g-c-Walla.cgcc-fPIC-g-c-Wallb.cgcc-shared-Wl,-soname,liblusterstuff.so.1-oliblusterstuff.so.1.0.1a.ob.o–lc注:”-fPIC”是位置无关参数,”-g”和“-Wall”参数不是必须的。Linux下函数库库(3/3)函数库和头头文件的保保存位置a.函数数库/lib::系统必备备共享函数数库/usr/lib:/usr/i486-linux-libc5/lib:libc5兼容性函数库/usr/X11R6/lib:X11R6的函数库/usr/local/lib:本地函数库b.头文件/usr/include:系统头文件/usr/local/include:本地头文件c.
共享函数库的相关配置和命令/etc/ld.so.conf:包含共享库的搜索位置ldconfig:共享库管理工具,一般在更新了共享库之后要运行该命令ldd:可查看可执行文件所使用的共享函数库使用GNUcc开开发应用程程序gcc的简简介可执行文件件的格式gcc的使使用gcc的简简介gcc是是GNU的C和C++编编译器。实实际上,gcc能能够编译多种语言:C、、C++和和ObjectC等。。利用gcc命命令可同时时编译并连连接C和和C++源程程序。也可可以对几个个C源源文件利用用gcc编译、、连接并生生成可执行行文件。gcc可可以以使使程程序序员员灵灵活活地地控控制制编编译译过过程程。。编编译译过过程程一一般般可可以以分分为为下下面面四四个个阶阶段段,,每每个个阶阶段段分分别别调调用用不不同同的的工工具具进进行行处处理理预处理链接编译组译源程序(*.c)可执行文件预处理器编译器组译器连接器gcc的的四四个个阶阶段段命令令gcc首首先先调调用用cpp进进行行预预处处理理,,在在预预处处理理过过程程中中,,对对源源代代码码文文件件中中的的文文件件包包含含(include)、、预预编编译译语语句句(如如宏宏定定义义define等等)进进行行分分析析。。接着汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S或.s为后缀的汇编语言源代码文件汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的函数库中连到合适的地方。可执执行行文文件件格格式式Linux系系统统中中可可执执行行文文件件有有两两种种格格式式。。第一一种种格格式式是是a.out格格式式,,这这种种格格式式用用于于早早期期的的Linux系系统统以以及及Unix系系统统的的原原始始格格式式。。a.out来来自自于于UnixC编编译译程程序序默默认认的的可可执执行行文文件件名名。。当当使使用用共共享享库库时时,,a.out格格式式就就会会发发生生问问题题。。把把a.out格格式式调调整整为为共共享享库库是是一一种种非非常常复复杂杂的的操操作作。。因此,一种新新的文件格式式被引入Unix系统5的第四版本本和Solaris系统统中。它被称称为可执行和和连接的格式式(ELF))。这种格式式很容易实现现共享库。ELF格式已已经被Linux系统作作为标准的格格式采用。gcc编译程程序产生的所所有的二进制制文件都是ELF格式的的文件(即使使可执行文件件的默认名仍仍然是a.out)。较较旧的a.out格式的的程序仍然可可以运行在支支持ELF格格式的系统上上。GNUC的的使用基本语法gcc[options][filenames]说明:在gcc后gcc-p-gtest1.cgcc-pgtest1.c当你不用任何选项编译一个程序时,GCC将会建立(假定编译成功)一个名为a.out的可执行文件。gcc选项-o选项你能用-o编译选项项来为将产生生的可执行文文件指定一个个文件名来代代替a.out。例:gcc––ocountcount.c-c选项:告告诉GCC仅仅把源代码编编译为目标代代码而跳过汇汇编和连接的的步骤。这个个选项使用的的非常频繁,,因为它使得得编译多个C程序时速度度更快并且更更易于管理。。缺省时GCC建立的目目标代码文件件有一个.o的扩展名。。例:gcc––ctest2.c-E只运行行C预编编译器。-S编译选选项告诉gcc在为为C代码码产生了汇编编语言文件后后停止编译。。-shared生成共共享目标文件件。通常用在在建立共享库库时。-static禁止警告选选项在gcc中中用开开关-Wall控制制警告告信息息,使使用示示例命命令如如下::gcc––Wall-otest3_1test3_1.c-w不不生生成任任何警警告信信息。。查找选选项gcc一般般使用用默认认路径径查找找头文文件和和库文文件。。如果果文件件所用用的头头文件件或库库文件件不在在缺省省目录录下,,则编编译时时要指指定它它们的的查找找路径径。-I选选项::指定定头文文件的的搜索索目录录例:gcc––I/export/home/st––otest1test1.c-L选选项::指定定库文文件的的搜索索目录录例:gcc––L/usr/X11/R6/lib––otest1test1.c多个源源文件件生成成一个个可执执行文文件问题::有多多个源源文件件时,,如何何生成成一个个可方法1:gcc–Wall–omytesttest1.ctest2.ctest3.c方法2:gcc-Wall-ctest1.cgcc-Wall–ctest2.cgcc-Wall–ctest3.cgcc–omytesttest1.otest2.otest3.o优化选选项优化选选项可可以使使GCC在在耗费费更多多编译译时间间和牺牺牲易易调试试性的的基础础上产产生更更小更更快的的可执执行文文件。。这些些选项项中最最典型型的是是-O和-O2选项项。-O0不不进行行优化化处理理。-O选选项::告诉诉GCC对对源代代码进进行基基本优优化。。这些些优化化在大大多数数情况况下都都会使使程序序执行行的更更快。。-O2选项项:告告诉GCC产产生尽尽可能能小和和尽可可能快快的代代码。。-O2选选项将将使编编译的的速度度比使使用-O时时慢。。但通通常产产生的的代码码执行行速度度会更更快。。-O3选项项:比比-O2更更进一版本本选选项-v选选项项用户户将将会会得得到到自自己己目目前前正正在在使使用用的的gcc的的版版本本及及与与版版本本相相关关的的一一些些信信息息。。gcc-v将将得得到到如如下下结结果果::Readingspecsfrom/usr/lib/gcc-lib/i486-box-linux/2.7.2/specsgccversion2.7.2-V选选项项如果果安安装装了了多多个个版版本本的的gcc,,并并且且想想强强制制执执行行其其中中的的某某个个版版本本,,可可以以用用命命令令通通知知系系统统用用户户要要使使用用的的版版本本。。gcc-V2.6.3-v宏定义选选项-DMACRO以以字符串串“1””定义MACRO宏宏。-DMACRO=DEFN以字字符串““DEFN”定定义MACRO宏宏。-UMACRO取取消对MACRO宏宏的定定义。调试和剖剖析选项项使用调试试选项后后,gcc在进进行编译译的时候候,在目目标文件件(.o)和创创建的可可执行文文件中插插入额外外信息,,这些额额外信息息使gdb能够够判断编编译过的的代码和和源代码码之间的的关系。。-g选项项:告诉诉GCC产生能能被GNU调调试器器使用的的调试信信息以便便调试你你的程序序。例:gcc––g––otest3test3.c-pg选选项:告告诉GCC在你你的程序序里加入入额外的的代码,,执行时时,产生生gprof用用的剖析析信息以以显示你你的程序序的耗时时情况。。使用gdb调试试工具,,命令行行如下::例:gcc––ggdb3––otest3test3.c调试工具具gdbGDB调调试器简简介gdb的的常用用命令gdb应应用实例例gdb简简介Linux系统统中包含含了GNU调调试程序序gdb,它是是一个用用来调试试C和C++程序序的调试试器。可可以使程程序开发发者在程程序运行行时观察察程序的的内部结结构和内内存的使使用情况况。gdb所所提供供的一些些功能如如下所示示:运行程序序,设置置所有的的能影响响程序运运行的参参数和环环境;控制程序序在指定定的条件件下停止止运行;;当程序停停止时,,可以检检查程序序的状态态;修改程序序的错误误,并重重新运行行程序;;动态监视视程序中中变量的的值;可以单步步逐行执执行代码码,观察察程序的的运行状状态。分析崩溃溃程序的的产生的的core文件件gdb的的特点gdb的的功能非非常强大大到目前为为止,gdb已已能够支支持Moduls-2、Chill、Pascal和FORTRAN程序的的调试,,但是调调试这些些语言的的源程序序时有一一些功能能还不能能使用。。例如调试试FORTRAN程序序时还不不支持表表达式的的输入、、输出变变量或类类FORTRAN的词词法。gdb程序调调试的对象是是可执行文件件,而不是程程序的源代码码文件。然而,并不是是所有的可执执行文件都可可以用gdb调试。如果果要让产生的的可执行文件件可以用来调调试,需在执执行gcc指指令编译程序序时,加上-g参数,指指定程序在编编译时包含调调试信息。调试信息包含含程序里的每每个变量的类类型和在可执执行文件里的的地址映射以以及源代码的的行号。gdb利用用这些信息
gdb的启动动在命令行上输输入gdb并并按回车键就就可以运行gdb了,如如果一切正常常的话,将启启动gdbgdb[filename]出现(gdb)在这里,可以以输入调试命命令在可以使用gdb调调试程序之前前,必须使用用-g选选项编译源文文件。可在make获取帮助信息息启动gdb后后,可以在命命令行上指定定很多的选项项。输入:help可以获得gdb的帮助信信息。如果想要了解解某个具体命命令(比如break))的帮助信息息,在gdb提示符下输输入下面的命命令:break屏幕上会显示示关于break的帮助助信息。从返返回的信息可可知,break是用于于设置断点的的命令。另一个获得gdb帮助的的方法是浏览览gdb的手手册页。在LinuxShell提示符输入入:mangdb可以看到man的手册页页gdb命令的的分类在gdb提提示符处处键入help,将列出出命令的分类类,主要的分分类有:aliases:命令别别名breakpoints:断点定义义;data:数数据查看;files::指定并查看看文件;internals:维维护命令;running:程序执执行;stack:调用栈栈查看;statu:状态查查看;tracepoints:跟跟踪程序执执行。后跟命令的的分类名,,可获得该该类命令的的详细清单单基本gdb命令(1/2)file命命令:装入入想要调试试的可执行行文件。cd命令::改变工作作目录。pwd命令令:返回当当前工作目目录。run命令令:执行当当前被调kill命令:停止正在调试的应用程序。list命令:列出正在调试的应用程序的源代码。break命令:设置断点。watch命令:设置监视点,监视表达式的变化。awatch命令:设置读写监视点。当要监视的表达式被读或写时将应用程序挂起。它的语法与watch命令相同。rwatch命令:设置读监视点,当监视表达式被读时将程序挂起,等侍调试。此命令的语法与watch相同。next命令:执行下一条源代码,但是不进入函数内部。也就是说,将一条函数调用作为一条语句执行。执行这个命令的前提是已经run,开始了代码的执行。基本gdb命令(2/2)step命命令:执行行下一条源源代码,进进入函数内内部。如果果调用了某某个函数,,会跳到函函数所在的的代码中等等候一步步步执行。执执行这个命命令的前display命令:在应用程序每次停止运行时显示表达式的值。infobreak命令:显示当前断点列表,包括每个断点到达的次数16)infofiles命令:显示调试文件的信息。17)infofunc命令:显示所有的函数名。18)infolocal命令:显示当前函数的所有局部变量的信息。19)infoprog命令:显示调试程序的执行状态。20)print命令;显示表达式的值。21)delete命令:删除断点。指定一个断点号码,则删除指定断点。不指定参数则删除所有的断点。22)Shell命令:执行LinuxShell命令。23)make命令:不退出gdb而重新编译生成可执行文件。24)Quit命令:退出gdb。gdb使使用实例((1/2))/*一个个有错误的的C源源程序*/#include<stdio.h>#include<stdlib.h>staticcharbuff[256];staticchar*string;intmain(){printf("Pleaseinputgets(string);printf("\nYourstringis:%s\n",string);}上面这个程序非常简单,其目的是接受用户的输入,然后将用户的输入打印出来。该程序使用了一个未经过初始化的字符串地址string,因此,编译并运行之后,将出现SegmentFault错误:$gcc-otest-gtest.c$./testPleaseinputastring:asfdSegmentationfault(coredumped)gdb使使用实例((2/2))为了查找该该程序中出出现的问题题,我们利利用gdb,并按按如下的步步骤进行::1.运行gdbbugging命命令,装装入bugging可执执行文件;;2.执行装装入的bugging命命令;3.使用where命令令查看程序序出错的地地方;4.利用list命令查查看调用gets函数附附近的代码码;5.唯一能能够导致gets函数出出错的因素素就是变量量string。。用print命命令查看看string的的值;6.在gdb中中,我们可可以直接修修改变量的的值,只要要将string取一个个合法的指指针值就可可以了,为为此,我我们在第11行行处设置断断点;7.程序重重新运行到到第11行处停停止,这时时,我们可可以用setvariable8.然后继续运行,将看到正确的程序运行结果。GNUmake概概述Makefile的的基本结结构Makefile中中的变量GNUmake的Makefile的隐含规则make命令行选项使用automake和autoconf产生MakefileGNUmake概概述在大型的开开发项目中中,人们通通常利用make工具来来自动完成成编译工作作。这些工工作包括::如果仅修改改了某几个个源文件,,则只重新新编译这几几个源文件件;如果某个头头文件被修修改了,则则重新编译译所有包含含该头文件件的源文件件。利用这种自自动编译可可大大简化化开发工作作,避免不不必要的重重新编译。。实际上,make工工具通过过一个称为为makefile的文文件来完成成并自动维维护编译工工作。makefile需需要按照某某种语法进进行编写,,其中说明明了如何编编译各个源源文件并连连接生成可可执行文件件,并定义义了源文件件之间的依依赖关系。。当修改改了其中某某个源文件件时,如果果其他源文文件依赖于于该文件,,则也要重重新编译所所有依赖该该文件的源源文件。默认情况下下,GNUmake工具具在当前工工作目录按按如下顺序序搜索makefile::GNUmakefilemakefileMakefilemakefile举举例在UNIX中,习惯惯使用makefile作作为makfile文件件。Linux程序员使使用第三种种文件名Makefile。。因为第一一个字母是是大写,通通常被列在在一个目录录的文件列列表的最前前面。如果要使用用其他文件件作为makefile,,则可利用用类似下下面的make命命令选项项指定makefile文文件:$make-fMa例1:一个简单的makefile
prog:prog1.oprog2.o
gccprog1.oprog2.o-oprog
prog1.o:prog1.clib.h
gcc-c-I.-oprog1.oprog1.c
prog2.o:prog2.c
gcc-cprog2.cMakefile的的基本结结构(1/2)Makefile是是一个文本本形式的数数据库文件件,其中包包含一些规规则来告诉诉make处理哪些些文件以及及如何处理理这些文件件。规则主要是是描述哪些些文件(称称为target目目标文件,,不要和编编译时产生生的目标文文件相混淆淆)是从哪哪些别的文文件(称为为dependency依赖赖文件)中中产生的,,以及用什什么命令((command))来执行这这个过程。。目标文件不一定是最后的可执行文件,可以是任何一个中间文件并可以作为其他目标文件的依赖文件。Makefile的的基本结结构(2/2)Makefile规规则的一般般形式如下下:target:dependencydependency(tab)<command>一个Makefile文件主主要含有一一系列的规规则,每条条规则包含含以下内容容。一个目标((target),,即make最终需需要创建的的文件,如如可执行文文件和目标标文件;目目标也可以以是要执行行的动作,,如“c一个或多个依赖文件(dependency)列表,通常是编译目标文件所需要的其他文件。一系列命今(command),是make执行的动作,通常是把指定的相关文件编译成目标文件的编译命令,每个命令占一行,且每个命令行的起始字符必须为TAB字符。除非特别指定,否则make的工作目录就是当前目录。target是需要创建的二进制文件或目标文件,dependency是在创建target时需要用到的一个或多个文件的列表,命令序列是创建target文件所需要执行的步骤,比如编译命令。Makefile实例例(1/3)#以#开头的的为注释释行test:prog.ocode.ogcc––otestprog.ocode.oprog.o::prog.cprog.hcode.hgcc––cprog.c–oprog.ocode.o::code.ccode.hgcc––ccode.c–ocode.oclean:rm––f*.o上面的Makefile文件件中共定定义了四四个目标标:test、、prog.o、code.o和clean。目标从每每行的最最左边开开始写,,后面跟跟一个冒冒号(::),如如果有与与这个目目标有依依赖性的的其他目目标或文文件,把把它们列列在冒号号后面,,并以空空格隔开开。然后后另起一一行开始始写实现现这个目目标的一一组命令令。在Makefile中中,可使使用续行行号(\)将一一个单独独的命令令行延续续成几行行。但要要注意在在续行号号(\))后面不不能跟任任何字符符(包括Makefile实例例(2/3)一般情况况下,调调用make命命令可输输入:#maketargettarget是是Makefile文文件中定定义的目目标之一一,如果果省略target,,make就将将生成Makefile文件件中定义义的第一一个目标标。对于上面面Makefile的的例子,,单独的的一个““make”命命令等价价于:#maketest因为test是是Makefile文文件中定定义的第第一个目目标,make首先将将其读入入,然后后从第一一行开始始执行,,把第一一个目标标test作为为它的最最终目标标,所有第一条规则说明只要文件test的时间戳比文件prog.o或code.o中的任何一个旧,下一行的编译命令将会被执行。Makefile实例例(3/3)但是,在在检查文文件prog.o和code.o的的时间戳戳之前,,make会在在下面的的行中寻寻找以prog.o和和code.o为目标标的规则则,在第第三行中中找到了了关于prog.o的的规则,,该文件件的依赖赖文件是是prog.c、prog.h和code.h。。同样,以同样的方法,接下来对文件code.o做类似的检查,依赖文件是code.c和code.h。当make执行完所有这些套嵌的规则后,make将处理最顶层的test规则。如果关于prog.o和code.o的两个规则中的任何一个被执行,至少其中一个.o目标文件就会比test新,那么就要执行test规则中的命令,因此make去执行gcc命令将prog.o和code.o连接成目标文件test。在上面Makefile的例子中,还定义了一个目标clean,它是Makefile中常用的一种专用目标,即删除所有的目标模块make的工作作过程现在来看看一下make做的工工作:首先make按按顺序读读取makefile中的规规则,然后检查查该规则则中的依依赖文件件与目标标文件的的时间戳戳哪个更更新如果目标标文件的的时问戳戳比依赖赖文件还还早,就就按规则则中定义义的命令令更新目目标文件件。如果该规规则中的的依赖文文件又是是其他规规则中的的目标文文件,那那么依照照规则链链不断执执行这个个过程,,直到Makefile文件件的结束束,至少少可以找找到一个个不是规规则生成成的最终终依赖文文件,获获得此文文件的时时间戳然后从下下到上依依照规则则链执行行目标文文件的时时间戳比比此文件件时间戳戳旧的规规则,直直到最顶顶层的规规则通过以上上的分析析过程,,可以看看到make的的优点,,因为.o目标标文件依依赖.c源文件件,源码码文件里里一个简简单改变变都会造造成那个个文件被被重新编编译,并并根据规规则链依依次由下下到上执执行编译译过程,,直到最最终的可可执行文文件被重重新连接接。例如,当Makefile中的的变量Makefile里的的变量就就像一个个环境变变量。事事实上,,环境变变量在make中也被被解释成成make的变变量。这这些变量量对大小小写敏感感,一般般使用大大写宇母母。几乎乎可以从从任何地地方引用用定义的的变量,,变量的的主要作作用如下下:保存文件件名列表表。在前前面的例例子里,,作为依依赖文件件的一些些目标文文件名出出现在可可执行文文件的规规则中,,而在这这个规则则的命令令行里同同样包含含这些文文件并传传递给gcc做做为命令令参数。。如果使使用一个个变量来来保存所所有的目目标文件件名,则则可以方方便地加加入新的的目标文文件而且且不易出出错。保存可执执行命令令名,如如编译器器。在不不同的Linux系统统中存在在着很多多相似的的编译器器系统,保存编译器的参数。在很多源代码编译时,gcc需要很长的参数选项,在很多情况下,所有的编译命令使用一组相同的选项,如果把这组选项使用一个变量代表,那么可以把这个变量放在所有引用编译器的地方。当要改变选项的时候,只需改变一次这个变量的内容即可。变量的定定义和使使用Makefile中的的变量是是用一个个文本串串在Makefile中定义义的,这这个文本本串就是是变量的的值。只只要在一一行的开开始写下下这个变变量的名名字,后后面跟一一个“==”号,,以及要要设定 VARNAME=string使用时,把变量用括号括起来,并在前面加上$符号,就可以引用变量的值: ${VARNAME}make解释规则时,VARNAME在等式右端展开为定义它的字符串。变量一般都在Makefile的头部定义。按照惯例,所有的Makefile变量都应该是大写。如果变量的值发生变化,就只需要在一个地方修改,从而简化了Makefile的维护。Makefile变变量举举例现在利利用变变量把把前面面的MakefileOBJS=prog.ocode.oCC=gcc
test:${OBJS} ${CC}–otest${OBJS}
prog.o:prog.cprog.hcode.h ${CC}–cprog.c–oprog.o
code.o:code.ccode.h ${CC}–ccode.c–ocode.o
clean: rm–f*.o变量的的类型型除用户户自定定义的的变量量外,,make还允允许使使用环境变变量使用环环境变变量的的方法法很简简单,,在make启启动时需要注意的是,如果用户在Makefile中定义了同名的变量,用户自定义变量将覆盖同名的环境变量自动变量预定义变量GNUmake的的主主要预预定义义变量量(1/2)$*不不包含含扩展展名的的目标标文件件名称称。$+所所有有的依依赖文文件,,以空空格分分开,,并以以出现现的先先后为为序,,可能能包含含重复复的依依赖文文件。。$?所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。$@目标的完整名称。$^所有的依赖文件,以空格分开,不包含重复的依赖文件。$%如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为mytarget.so(image.o),则$@为mytarget.so,而$%为image.o。AR归档维护程序的名称,默认值为ar。ARFLAGS归档维护程序的选项。AS汇编程序的名称,默认值为as。ASFLAGS汇编程序的选项。GNUmake的的主主要预预定义义变量量(2/2)CCC编编译译器的的名称称,默默认值值为cc。CFLAGSC编编译译器的的选项项。CPPC预预编译译器的的名称称,默默认值值为$(CC)-E。CPPFLAGSC预预编译译的选选项。。CXXC++编编译器器的名名称,,默认认值为为g++。CXXFLAGSC++编编译器器的选选项。。FCFORTRAN编编译器器的名名称,,默认认值为为f77。FFLAGSFORTRAN编编译器器的选选项。。Makefile的的隐含含规则则在上面面的例例子中中,几几个产产生目目标文文件的的命令令都是是从““.c”的的C语语言源源文件件和相相关文文件通通过编编译产产生““.o”目目标文文件,,这也也是一一般的的步骤骤。实实际上上,make可可以使使工作作更加加自动动化,,也就就是说说,make知知道一一些默默认的的动作作,它它有一一些称称作隐隐含规规则的的内置置的规规则,,这些些规则则告诉诉make当用用户没没有完完整地地给出出某些些命令令的时时候,,应该该怎样样执行行。例如,把生生成prog.o和和code.o的命命令从规则则中删除,,make将会查找找隐含规则则,然后会会找到并执执行一个适适当的命令令。由于这这些命令会会使用一些些变量,因因此可以通通过改变这这些变量来来定制make。象象在前面的的例子中所所定义的那那样,make使用用变量CC来定义编编译器,并并且传递变变量CFLAGS((编译器参参数)、CPPFLAGS((C语言预预处理器参参数)、TARGET_ARCH(目目标机器的的结构定义义)给编译译器,然后后加上参数数-c,后后面跟变量量$<(第第一个依赖赖文件名)),然后是是参数-o加变量$@(目标标文件名))。综上所述,,一个C编编译的具体体命令将会会是:${CC}${CFLAGS}${CPPFLAGS}${TARGET_ARCH}–c$<-o$@隐含规则举举例在上面的例例子中,利利用隐含规规则,可以以简化为::OBJS=prog.ocode.oCC=gcctest::${OBJS}${CC}––o$@$^prog.o:prog.cprog.hcode.hcode.o:code.ccode.hclean:rm–f*.omake命命令行选项项直接在make命命令的后后面键入目目标名可建建立指定的的目标,如如果直接运运行make,则则建立第一一个目标。。还可以用用make-fmymakefileGNUmake命令还有一些其他选项,下面是GNUmake命令的常用命令行选项命令行选项含义:-CDIR在读取makefile之前改变到指定的目录DIR。-fFILE以指定的FILE文件作为makefile。-h显示所有的make选项。-i忽略所有的命令执行错误。-IDIR当包含其他makefile文件时,可利用该选项指定搜索目录。-n只打印要执行的命令,但不执行这些命令。-p显示make变量数据库和隐含规则。-s在执行命令时不显示命令。-w在处理makefile之前和之后,显示工作目录。-WFILE假定文件FILE已经被修改。使用automake和autoconf产生生Makefil在开始使用用Automake和autoconf之前,,请先确认认系统已经经安装以下下的软件::GNUAutomakeGNUAutoconfGNUm4PerlGNULibtool(如果你你需要产产生sharedlibrary)Automake所所产生的的Makefile除了了可以做做到程序序的编译译和连接接,也已已经把如如何产生生程序文文件的操操作,以以及把安安装程序序都考虑虑进去了了,所以以源程序序所存放放的目录录架构最最好符合合GNU的标准准惯例,,下面用用hello.c来来作为例例子进行行说明。。生成一个个源程序序在工作目目录下建建立一个个新的子子目录dev用编辑器写个hello.c文件:#include<stdio.h>intmain(intargc,char**argv){printf("Hello,GNU!\n");return0;}使用Autoconf及及Automake来产产生Makefile文件的的步骤autoscan产产生一个个configure.in的模板板,执行行autoscan后会会产生一一个configure.scan的文文件,可可以用它它做为configure.in文文件的模模板:编辑configure.scan文件,,如下所所示,并并且把文文件名改改成configure.in执行aclocal和和autoconf,,分别别会产生生aclocal.m4及及configure两两个文文件:编辑Makefile.am文件,,内容如如下:执行automake--add-missing,,Automake会根根据Makefile.am产生生一些文文件,包包含最重重要的Makefile.in:最后执行行./configure使用RCS/CVS来来管理源源代码RCS的的使用CVS的的使用RCS的的使用RCS((RevisionControlSystem))即程序序改版控控制系统统,主要要功能是是用来管管理文件件的版本本,可以以节省空空间和时时间。这这样就不不需要在在每个程程序开发发到某一一个阶段段就将数数据拷贝贝到其他他的地方方备份起起来了。。RCS提提供了如如下几个个最重要要的指令令的:ci指令令:将文文件放入入RCS目录下下的控制制系统co指令令:从RCS目目录下将将文件取取出rcs指指令:用用来对RCS文文件进行行参数的的设置基本操作作方式一般而言言,RCS所产产生出来来的文件件会放在在RCS目录中中。所以以第一步步必须要要在当前前的目录录下制作作一个文文件:[root@wyhlinux]#mkdirRCS接下来只只要使用用ci指指令。就就可以把把文件备备份到RCS改改版控制制系统中中:[root@wyhlinux]#citest.c若要将文文件取出出,可以以使用下下列指令令:[root@wyhlinux]#cotest.c取出来的的文件是是只读文文件,若若要取出出可以写写入的工工作文件件,可以以加上-l参数数来锁定定它:[root@wyhlinux]#co-ltest.c此外将文文件放入入RCS控制系系统时,,可以使使用-l参数锁锁定文件件,那么么目录下下的文件件依然存存在:[root@wyhlinux]#ci-ltest.c若要比较较当前的的文件和和RCS中最新新版本的的文件,,可以使使用下列列指令::[root@wyhlinux]#rcsdifftest.c指定版本本若不指定定版本编编号时,,co会会从RCS取得得最新的的版本。。如果要要以特定定的版本本号码写写入RCS或读读出,可可以使用用-r参参数选项项。[root@wyhlinux]#ci-l-r3.25test.c<--以以3.25作为为版本编编号[root@wyhlinux]#co-l-r1.2test.c<--将将RCS中1.2版的的test.c读出此外,rcsdiff也可以以用来指指定任何何一个版版本和当当前程序序代码进进行比较较。[root@wyhlinux]#rcsdiff-r3.25test.c<--取取出3.25版版与test.c进行行比较关键词的的使用在RCS中可以以将关键键词变量量放入程程序代码码中。这这些变量量经过RCS会会变成版版本的注注解。用用户可以以将这些些关键词词说明当当作是程程序中的的批注。。常用的关关键词如如下:$Author$:将将版本放放入RCS的用用户名称称。$Data$::记录程程序代码码放入RCS时时的日期期和时间间。$Header$:记记录文件件的标头头,包括括RCS路径名名称、版版本号码码、日期期、作者者等。$ID$:和$Header$相同同,但不不包括RCS路路径名称称。$Locker$:记记录锁定定本版本本的用户户名称。。$Log$:记记录将RCS锁锁住的时时间,所所输入的的文本语语句。$RCSfiles$:记录录RCS文件名名称。$Rivision$:指定定版本号号码。$Source$:RCS文文件名称称,包括括其路径径。$State$:使用用-s选选项所指指定的特特殊状态态使用关键键词的步步骤在程序代代码中加加入任一一关键词词[root@wyhlinux]#vitest.c将程序代代码放入入RCS版本控控制系统统[root@wyhlinux]#ci-ltest.c将文件再再次取出出。在取取出的过过程中,,co会会将每个个关键词词展开成成其对应应的值[root@wyhlinux]#co-ltest.c[root@wyhlinux]#cattest.cCVS的使用用CVS(ConcurrentVersionSystem)是是个版本控制制系统,利用用该系统可以以记录源代码码文件的历史史。例如,当当软件修改时时会产生Bug,并且可可能在做这次次修改后很长长时间不会发发现这些问题题。使用CVS就可以容容易地回顾老老的代码版本本去发现哪一如果CVS保留每一次的代码版本,会浪费很多的空间。因此CVS使用一种比较聪明的办法保存多个版本在一个文件中。它仅仅保留版本间的不同内容。如果很多人在同一个项目上工作,则CVS使用让不同开发者独立工作的方式解决了这个问题。每一个开发者的工作都在他自己的目录内,并且CVS将在每个开发者的工作完成后进行合并工作。在Linux下,CVS的使用一般是以命令行方式。通常,CVS有两种使用方式,一是本机方式,一是远程执行方式。CVS的命令格式是: cvs[cvs的选项]cvs的动作[选项]可以用cvs–Hcommand列出命令command的使用方法开始项目用CVS管理理代码,首先先要创建一个个“信息仓库库”。“信息息仓库”简单单来说包含一一个目录结构构。它包括要要管理的源代代码和用于管管理源代码的的各种管理文文件先设置环境变变量CVSROOT,指指向信息仓库库的绝对路径径,然后调用用CVS的init命令令:#CVSROOT=/usr/local/cvsroot;exportCVSROOT#cvsinit#ls-l$CVSROOT添加项目的文文件、目录到到信息仓库要将需要管理理的项目的文文件加入到信信息仓库,并并做上标志。。如果从头开开始一个新的的项目,就然后,就可以输入源文件目录: #cvsimport-m"CreateSourceDir"cvstest/cwucvstest这样会生成$CVSROOT/cvstest/c目录。其中-m用来指定注释信息,如果后面在命令行不指定注释信息,则会启动缺省编辑器(vi)要求输入注释信息;cvstest/c是项目名称(实际上是仓库名,在CVS服务器上会存储在以这个名字命名的仓库里);wu,cvstest分别标识了作者和发行标识。命令简介———导出源文件件(1/2)cvscheckout[-rrev][-Ddate][-ddir][-jmerg1][-jmerg2]modules-r导出指指定版本的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工程硕士研究生
- 第9课《从百草园到三味书屋》教学设计+2024-2025学年统编版语文七年级上册
- 2023-2024学年全国小学四年级上科学人教版期中考试试卷(含答案解析)
- 2024年银川客运资格证专业知识试题
- 2024年沈阳客运从业资格证试题答案
- 2024年昌都申请客运从业资格证模拟考试
- 2024年全新作品委托创作合同
- 2024年盘锦道路旅客运输从业资格证模拟试题
- 2019年山东东营中考满分作文《“高山”的力量》
- 2024年南宁客运从业资格证
- 湖南省邵阳市各县区乡镇行政村村庄村名居民村民委员会明细及行政区划代码
- 送达地址确认书(样本)
- 江苏省历届中学生与社会作文大赛决赛试题及获奖范文(完整版)资料
- OA系统技术要求
- 造价咨询项目交底及实施表
- 受委托实验室能力调查表
- 第四军医大学西京医院进修生申请表(官方版)
- 《民航服务礼仪》项目五 地面服务礼仪
- 自乂琐言-袁保庆
- 北京市水资源税讲解
- 钢筋组织供应、运输、售后服务方案
评论
0/150
提交评论