水晶球和解剖刀吧 关注:15贴子:478

[原创] FreeBSD系统编程[简体中文版]转自CU

只看楼主收藏回复

http://www.chinaunix.net/jh/89/699989.html
参考链接: 
[url=http://bbs.chinaunix.net/viewthread.php?tid=699102&extra=page%3D1]【FreeBSD system programming 】中文翻译计划及所有异义提交处 


1楼2008-07-06 07:29回复
    FreeBSD系统编程

    Copyright(C) 2001~2006 Nathan Boeger 和Mana Tominaga 版权所有,简体中文版由ChinaUnix论坛提供翻译。 

    目录 
    第一章: FreeBSD的Make 
    第二章: BSD自举 
    第三章: 进程和内核服务 
    第四章: 高级进程控制和信号 
    第五章: 基本I/O 
    第六章: 高级I/O 
    第七章: 进程资源和系统限制 
    第八章: FreeBSD 5.x


    2楼2008-07-06 07:30
    回复
      第一章 FreeBSD的make
      译者:雨丝风片@chinaunix.net

      1.1 FreeBSD的make 

      作为常用的和基本的Unix软件开发工具,make是一个可以跟踪全部的文件依赖关系的非常好的簿记工具程序。要管理依赖关系这样的项目细节常常需要花费很多的时间,甚至会拖延开发进度。当多个开发人员合作一个项目的时候,依赖关系的跟踪就可能变得相当困难了。事实上,正确地使用make可以帮助我们加快应用程序的开发,从而提高生产效率。 

      虽然make最初的设计是用来对应用程序版本构建的维护过程进行管理的,我们实际上还可以通过创建一系列的基于目标依赖关系的Unix shell命令来让make完成多种多样的额外工作。这些依赖关系可以用很多种方式定义——包括需要进行编译的源文件、所需的库文件、shell命令以及其它的目标。


      3楼2008-07-06 07:32
      回复
        make有多种风格的版本,其中包括GNU make和System V make。并不是在每个make版本中都有我们接下来讨论的那些特性,具体使用哪个版本完全取决于你的个人喜好。我们将主要关注跟随FreeBSD一起发布的make(也叫做bmake或pmake),尤其是如何通过它来编译和更新FreeBSD系统,也就是所谓的make world。虽然我们关注的是FreeBSD make,但我们在这里讨论的所有东西对于各种BSD版本来说都是适用的。 

        我们首先会讲述一个Makefile的基本文件布局和语法。如果这对于你来说太简单了,那你可以直接跳到本章结束处的示例部分去阅读。(注意,我们给出的代码示例只用于演示我们关于make目标和依赖关系的讨论,它们并不一定是可以运行的代码。) 

        当然,和其它工具程序一样,最开始应该先去看看man page,以对make提供的命令行选项的概要和细节有一个正式的了解。同时,和其它工具程序一样,学习make的最好方法就是使用它。创建一些小型的源文件(可以使用任何语言),然后尝试一些下面给出的例子。我们希望读完本章之后你除了理解make的语法规则之外,还知道它是如何工作的。


        4楼2008-07-06 07:34
        回复
          总的说来,你使用make的方式就是让它去读一个Makefile,你需要在Makefile里指定一个目标及其依赖关系。在运行的时候,make会按顺序搜索名字为Makefile或makefile的文件。这个Makefile通常是放在一个工程的根目录下的,如果想指定其它的Makefile,可以在命令行上用-f (filename)的选项给出。 


          make -f OtherMakefile


          5楼2008-07-06 07:35
          回复
            要使用make来编译一个工程,首先需要确定在你的当前工作目录中已有一个正确的Makefile,然后再通过下列命令之一来使用make: 


            bash$ make 

            bash$ make all 

            bash$ make <target name>


            7楼2008-07-06 07:36
            回复
              用来指定目标的方式有很多种,不过最常用的就是用目标文件或一个工程的名字。工程名字不应当包含有空格或标点符号,不过这只是个惯例而已;少量的空格和标点符号也是允许的。这个名字必须写在一个新行的开头,必须以单冒号(:)、双冒号(::)或感叹号(!)三者之一结束。 


              myprog:
               <some commands to the compile myprog target>

              another::
               <some commands to the compile another target>

              sample!
               <some commands to the compile sample target>


              8楼2008-07-06 07:37
              回复
                在这些目标名字之后是所需的依赖条件,包括名字、变量以及其它的目标等等。如果你的依赖条件太多的话,可以用一个‘\’和一个newline来将它们分开。所有的依赖条件都必须Makefile内定义或者存在于某个外部文件中,否则make将无法知道如何去完成依赖操作。 

                一些示例如下: 


                all: driver.cpp network_class.cpp file_io_class.cpp network_libs.cpp file_io_libs.cpp

                all: myprog.o 

                myprog.o:


                9楼2008-07-06 07:38
                回复
                  上例中,all和myprog.o是要make的目标。注意myprog.o既是一个目标又是一个依赖条件。make首先会到myprog.o那儿,执行它的命令,然后返回到all那儿,再执行它的命令。这种操作序列是make的功能基础。 

                  按照惯例,all:目标是你的目标中的最高者,这意味着make将从这儿开始去寻找要完成all:目标都需要哪些东西。不过all:目标并不是必需的,如果没有的话,make就会简单地选择所有列出的目标中的第一个,只对其实施操作,除非你在命令行上指定了某个目标。对于那些有一个核心的应用程序需要维护和构建的工程来说,我们建议你使用all:目标;这是一个通用的惯例,有助于避免错误和不必要的任务。


                  10楼2008-07-06 07:39
                  回复
                    上例所示的依赖序列只是很简单的一个。下面是一个更为复杂和灵活的依赖序列,我们没有给出用于具体目标的命令: 


                    all: myprog.o lib

                    lib: lex

                    lex:

                    myprog.o: app.h


                    11楼2008-07-06 07:39
                    回复
                      注意,在这个例子中,all:目标有两个依赖条件:myprog.o和lib。这两个依赖条件本身又都是目标,make将首先去编译myprog.o。在make编译myprog.o的时候,会发现有一个和app.h的依赖关系。app.h并没有在这个makefile里定义,但app.h却是一个在当前目录中的头文件。 

                      用于myprog.o的命令完成之后,make即返回到all:处,继续处理下一个依赖条件,在此例中是lib。依赖条件lib本身也有一个依赖条件lex,所以make在完成lib之前会先去完成lex:。 

                      注意:正如你所看到的,这些依赖关系可能会非常长,或者嵌套得很深。如果你有一个很大的Makefile,那一定要好好地组织一下,把目标的顺序弄好。 


                      ........................................

                      下次:http://www.chinaunix.net/jh/89/699989.html

                      第一章 FreeBSD的make 1.5 求值规则


                      12楼2008-07-06 07:41
                      回复
                        依赖关系是按照依赖于目标名字结束符号的严格规则来求值的。一旦make认为满足规则,它将通过执行相应的命令来创建特定的目标(比如编译该目标)。例如,使用单冒号:可以让你对需要进行编译的目标进行更为精细的控制。也就是说,你可以指定某个特定的目标文件每次都需要重新编译或者仅当它的源文件过时之后才编译。这些规则都是基于目标名字的结束符号的,如下:


                        13楼2008-07-06 13:20
                        回复
                          如果目标名字以单冒号(:)结束,它将根据以下两个规则来创建: 
                          [list=1] 
                          [*]如果目标尚未存在,就像我们在上面举的例子里的all:一样,make就会创建它。 
                          [*]如果任意一个源文件具有比当前目标更新的时间戳。在上例中如果app.h或myprog.c具有更新的时间戳,myprog.o就会被make。这种情况只需简单地用一下touch命令即可出现 
                          [/list] 

                           touch myprog.c


                          14楼2008-07-06 13:21
                          回复
                            如果目标名字以双冒号(::)结束,它将根据以下三个规则来创建: 
                            [list=1] 
                            [*]如果任意一个源文件具有比当前目标更新地时间戳。 
                            [*]该目标不存在。 
                            [*]该目标没有与之关联的源文件。 
                            [/list] 

                            如果目标名字以感叹号(!)结束,只要make把它所需的全部依赖条件都创建完毕就会来创建它。


                            15楼2008-07-06 13:22
                            回复
                              你只能在目标或源文件的最后一个组成部分中使用通配表达式?、*和[],而且只能用于描述已经存在的文件。比如: 


                              myprog.[oc]


                              而使用花括号{}的表达式则不一定非得描述已经存在的文件。比如: 


                              {mypgog,test}.o

                              # the expression above would match myprog.o test.o only


                              最后需要注意一点:可变表达式是按照目录顺序来处理的,而非字母顺序,就跟在shell表达式中一样。例如,如果你的目标有某些基于字母顺序的依赖条件,下面这个表达式可能就不对了: 


                              {dprog,aprog,bprog,cprog}.cpp


                              16楼2008-07-06 13:22
                              回复