zoukankan      html  css  js  c++  java
  • [内核分析]LXR安装心得(0.9.1版)

    因为网络不通,无法使用服务器上的lxr,严重影响我阅读代码的效率,所以索性自己找来了LXR的最新版lxr-0.9.1,在本地机上试着安装一份。
    LXR是使用WEB方式下的源代码整理浏览工具,最大的用途在于清理出了代码中函数、变量的定义、说明、应用的关系,并用链接的形式表现在网页上。LXR整理出代码的结构和调用关系,存在数据库中,并在显示时与源代码树结合,从功能上说,包括代码浏览、标识符搜索、文本搜索和文件搜索,其中的文本搜索和文件搜索利用的是第三方工具(即glimpse或swish-e)。它的主要组成部分包括三个:Perl编写的网页/CGI部分,基于MySQL的索引数据管理(新版本才有)和通用的文本搜索工具。目前的版本,采用Glimpse或者Swish-e中的一种作为通用文本搜索工具。在安装上,基本上也按照这三个部分来配置。
    1.download
    现在LXR已经成为sourceforge的一个project,所以可以到lxr.sourceforge.net上找到最新的lxr代码(当然也就是源代码了)。glimpse和swish-e另找。
    要使LXR工作,至少需要以下部件:
    一个支持CGI的Web服务器,Apache就不错;
    Apache的mod_perl插件,以支持perl脚本的cgi解释,或者直接用Perl也可以;
    MySQL或者Postgres,本人用的是MySQL;
    ctags包,一般都有。
    2.configure
    尽管lxr源码里有一个INSTALL文件,但语焉不详,这里写下的是本人的配置经验,不一定是唯一的,也不一定是最佳的。
    1)位置规划
    LXR除了数据库那一部分不需要考虑存放位置以外,还有CGI/HTML部分、索引生成工具部分和所需要索引的源代码部分需要考虑,我的实践中使用的与INSTALL缺省的不同,最大的一点不同在于我将WEB部分和工具部分分离开,只允许WEB部分暴露给浏览器——主要是基于也许会更安全一些的考虑。
    另一个不同是用符号链接而不是真正的源代码目录作为源代码部分,因为LXR索引的Linux Kernel是最常用的,而Kernel本身还被用来重编内核和升级,所以不适合完全拷贝过来。
    本例中使用的是/usr/local/lxr目录作为LXR的根目录。
    #tar zxvf lxr-0.9.1.tar.gz -C /usr/local ;将lxr解压到/usr/local/lxr下
    #cd /usr/local/lxr
    #mkdir http ;建http目录,用于存放WEB部分
    #mv Local.pm diff fixhashbang ident find search source templates/* http
    ;将web相关部分移到http下
    #rm -rf templates ;这个模板目录已经没用了
    #ln http/Local.pm . -s
    #ln http/lxr.conf . -s ;为web部分和工具部分都需要用的文件建符号连接
    #mkdir src ;源代码部分的根
    #cd src
    #mkdir kernel ;内核代码目录
    #vi versions ;编辑/usr/local/lxr/src/versions文件,内容为kernel,表示让lxr索引kernel
    #cd kernel
    #ln ../../../../src/linux-2.4.18 2.4.18 -s ;2.4.18才是真正的kernel源码根,之所以这么安排,主要是为了避免glimpse建索引时弄脏了/usr/src/linux-2.4.18/
    #cd ../../ ;回到/usr/local/lxr
    #mv lib /usr/lib/perl5/site_perl/LXR ;将自定义的perl库文件拷贝到perl/mod_perl使用的缺省库文件目录中,这是相对于redhat系统的
    2)改写lxr.conf
    准备好了目录结构,下一步就是改写lxr.conf文件。缺省的lxr.conf已经从templates拷贝到/usr/local/lxr/http/下了,并在/usr/local/lxr/下有个连接。
    'glimpsebin'变量,改为glimpse命令的位置,用which glimpse可以找到(如果装了的话),缺省为/usr/bin/glimpse;
    注释掉所有与swish-e相关的变量定义,——因为我编译swish-e时,make test执行了两天一夜也没有结束,所以只好改用glimpse,据说swish-e更强大些;
    'genericonf'设为'/usr/lib/perl5/site_perl/LXR/Lang/generic.conf';
    'baseurl'设为'http://10.129.6.244/lxr',这个IP当然不是通用的;
    'range'改为[ readfile('/usr/local/lxr/src/versions') ],用绝对路径,主要是为了方便;
    'default'改为'kernel',我自己定义的缺省的代码树名;
    'sourceroot'设为'/usr/local/lxr/src',也用绝对路径;
    'sourcerootname'设为'Linux',自定义的,它将显示在缺省的最高级源码目录上;
    'glimpsedir' => '/usr/local/lxr/src/$v/',$v表示使用version变量的值,也就要求把glimpse的索引结果文件保存在/usr/local/lxr/src/kernel上,与2.4.18并列;
    其余都不用改。
    3)apache的httpd.conf
    保证装了mod_perl的时候,在httpd.conf中添加以下几行:
    Alias /lxr /usr/local/lxr/http
    <Directory /usr/local/lxr/http>
    AllowOverride None
    Options FollowSymLinks
    <Files ~ (search|source|ident|diff|find)$>
    SetHandler perl-script
    PerlHandler Apache::Registry
    Options +ExecCGI
    </Files>
    </Directory>
    表示访问/lxr就相当于访问/usr/local/lxr/http,且用perl解释search、source、ident、diff和find几个脚本,而其他的仍然当成html来使用。
    如果没有mod_perl,可以用SetHandler cgi-script代替perl-script,一样可以用,PerlHandler就不用了。
    3.initialize
    1)初始化MySQL数据库
    运行mysql,在提示符下运行"\. initdb-mysql"。这样就建好了lxr用户,建好了lxr数据库可其中一系列表格,并让lxr能全权访问lxr数据库,但没有访问其他库的权限,而且,也不用密码。
    2)建glimpse索引
    在/usr/local/lxr/src/kernel/下运行'find . -name "*.[chS]" -follow | glimpseindex -H . -o -F',索引所有.c、.h、.S(汇编)文件。这个过程比较耗时,但比起下一个过程来,就小巫见大巫了。
    3)建identity索引
    这是LXR精髓所在,在/usr/local/lxr/下运行'./genxref --version=kernel --url=http://10.129.6.244/lxr',这个过程在我的机器上用了5个小时,其结果就是在MySQL中添东西。如果已经做过索引了,它就只关心那些修改过的或新的文件,速度就快多了。这个过程如果中断了,最好清空数据库重新来过,否则可能会有错误。
    4)修改权限
    最简单的办法就是把/usr/local/lxr/http下所有的文件都改成apache的属主。在/usr/local/lxr/下运行'chown apache.apache http -R'。
    4.startup
    重启mysql和httpd,然后访问http://10.129.6.244/lxr/source/就可以了。比较奇怪的是,因为这个cgi允许用类似目录一样的形式(source/)来访问,所以,如果服务器端有更新,浏览器端仍会使用老的页面,refresh也没用。这时只有清空本地cache了。
    5.update
    我还没有遇到更新的情况,但估计2.4.18升级到2.4.19时比较麻烦,因为目录名变了,而数据库里存的仍然是老名字,glimpse也用的老名字,所以更新可能需要重建一次数据索引,就是重新来一次3.initialize。
    但如果仅仅是添加新的源代码树,则只需要修改src/versions文件,按照kernel/2.4.18的模子再在src下建一个目录树,并一样执行一次3.2、3.3、3.4就可以了。为了方便,我把3.x做成了两个脚本。
    6.bugs
    应该在源代码树的组织上。如果同时要索引kernel-2.4.18和kernel-2.2.19,逻辑上好像应该在kernel下建另一个连接指向2.2.19的代码,但实际上应该建一个kernel2与kernel并列在src目录下。
    更新时看样子也会有问题,因为数据库里记录了2.4.18的目录信息,glimpse里也记录了2.4.18。重建实在耗时。
    不知谁有更好的配置方案,尽管这做不了博士课题。

    不知道有没有遗漏的地方。还多亏参考了别人已有的配置,尽管版本不同。

    FIXIT:
    1.在Config.pm中有一段处理baseurl的代码(_initialize()),屏蔽了所有config变量的生成。只能注释掉才能使其正常工作。
    2.缺省情况下,glimpse采用case insensitive方式工作(search程序),需要去掉"-i"的开关。

    ---------------------------------------------------------------------------------------------------------------------------------------------

    前段时间因为工作需要,从源码开始配置了apache2+modperl2+lxr-0.9.2,有些地方和本文所说不
    同,所以把更新内容贴在这里,希望对后来者有用。
    --------------
    更新 040628:
    1.从perl源码安装时没有DBI和DBD::mysql,需要自行安装。
    DBI和DBD::mysql的源代码都可以直接从google中找到,下载后perl
    Makefile.PL、make、make install即可。
    2./usr/lib/perl5/site_perl下需要有一份Local.pm的链接,/usr/local/lxr下倒是不需要。
    3.source脚本里使用的internal-gopher-*图片都不能正常显示,可能是mozilla或者是别的什么浏
    览器的设置。需要恢复成注释掉的/icons/目录下的相应图片,这些图片apache的缺省安装都有。
    4.不知道为什么,http目录下的那些template HTML文件在各个脚本里都打不开(doesn't
    exist),除非将其拷贝到系统根目录(“/”)。没办法,只能在lxr.conf中使用绝对路径来说明
    这些templates。
    5.html-head.html和html-tail.html中都含有一些指向internet的图片链接,最简单的办法就是去
    掉那个<img>。
    6.swish-e的配置很简单,只要设置好lxr.conf中的变量就可以
    了。但“file search”功能没有实现使用swish-e的版本,如果
    要用,只能继续使用glimpse。glimpse的配置因为版本的变化
    而和以前有所不同,而且在lxr.conf中已经没有glimpseindex的
    变量定义了,需要手工添加。
    7.swish-e的索引文件现在统一放在src/index目录下,因为
    genxref会用'$version'作为索引文件的文件名前缀,因而可以放
    在同一个目录下。
    8.lxr可能原本用于同一软件的不同版本的源代码索引,例如
    Linux的不同版本,因此它的version变量应该是代码的版本号,
    但这里直接用这个版本号指向了不同的代码树。本来lxr索引的
    不同版本的代码是可以diff markup的,现在这个功能也就同时
    失去了意义。
    9.使用mod_perl2的apache2的httpd.conf文件变化不大,只需要
    将Apache::Registry改为ModPerl::Registry。
    10.样例中的lxr.conf有两个swishdir和两个glimpsedir,后面那
    一对实际上可以删除。
    11.现在直接将代码拷贝到src目录下,而不是像以前那样在src
    的子目录里再作目录链接,也就是说,少了一层目录。
    12.html-ident.html最后那个table是冗余的,应该删除。
    13.httpinit函数最后调用了printhttp来显示一些信息,但这些信
    息会影响lxr输出的美观(位于题头),所以在
    LXR::Common.pm中注释掉了。
    14.0.9.2版的lxr把freetext索引和identity索引都集中在genxref脚
    本中进行,且4.17版的glimpseindex不支持管道输入。
    15.将glimpsedir设为"/usr/local/lxr/src/index",glimpseindex将
    把索引文件建立在$glimpsedir/$release/目录下。这时应当修改
    find和search,当它输出文件名时忽略掉$config->sourceroot/
    $release/的前缀。和以前的配置相比,这一修改是当前仅有一
    层源码目录引起的。
    16.最终还是选用glimpse,因为它的freetext索引中有简短的上
    下文。
    更新040708:
    因为发现lxr在Linux的几个浏览器下都只显示HTML代码,
    所以怀疑是因为注释了printhttp()而缺少HTML Header,但加上
    这个函数后仍然如此,HTML头信息直接显示在HTML代码最前
    面。
    参考linux-forum上tcpwl的配置,在httpd.conf中加上
    “ForceType text/html”,就可以正确显示了。
    如此设置后,printhttp()打印的几行Header信息仍然显示了
    出来,仍然是参考tcpwl的配置,加上“PerlOptions ParseHeaders”,
    但浏览时报错,说缺少http头。
    注释掉printhttp()中“Content-Type”之前的两个打印语
    句,总算正常了。
    现在的httpd.conf中与lxr相关的部分如下:
    ----------

    Alias /lxr /usr/local/lxr/http
    <Directory /usr/local/lxr/http>
            AllowOverride None
            Options FollowSymLinks
            <Files ~ (search|source|ident|diff|find)$>
             SetHandler perl-script
             PerlHandler ModPerl::Registry
             PerlOptions ParseHeaders
             Options +ExecCGI
            </Files>
            ForceType text/html
    </Directory>
     




    现在的lxr.conf如下:
    -----------

    # -*- mode: perl -*-
    # Configuration file
    #
    (
     {
      # Global configuration
    
      # Path to glimpse executable.
      # Define this OR the swish-e variables depending which search engine you want to
    use.
      'glimpsebin'	=> '/usr/local/bin/glimpse',
      'glimpseindex'	=> '/usr/local/bin/glimpseindex',
    
      # Where to store the glimpse index files
      'glimpsedir' => '/usr/local/lxr/src/index',
    
      # Location of SWISH-E indexer binary
    #  'swishindex' => '/usr/local/bin/swish-e',
    
      # Location of SWISH-E search binary
    #  'swishsearch' => '/usr/local/bin/swish-e',
    
      # Where to store the swish index files
    #  'swishdir' => '/usr/local/lxr/src/index/',
    
      # Path to Exuberant Ctags executable
      'ectagsbin'	=> '/usr/bin/ctags',
    
      # Place where lxr can write temporary files
      'tmpdir'		=> '/tmp',
    
      # Location of the Generic.pm config file
      'genericconf' => '/usr/lib/perl5/site_perl/LXR/Lang/generic.conf'
    
     },
    
     {
         # Configuration for href=http://192.168.1.3/lxr.>http://192.168.1.3/lxr.
         # baseurl is used to select configuration block.
    
         'baseurl'		=> 'http://172.16.109.67/lxr',  # Put your URL here
         'virtroot'		=> '/lxr',                    # The bit after the / above
         
         'variables' => {
    					 # Define typed variable "v".  This is the list of versions to index.
    					 'v' => {'name'    => 'Version',
    							 # This can come from a file, a function or be explicitly
    							 # ennumerated.
    							 # From a file:
    							 'range'   => [ readfile('/usr/local/lxr/src/versions') ], 
    							 # Explicitly:
    							 # 'range' => [qw(v1 v2 v3.1 v4 experimental)],
    							 # If files within a tree can have different versions,
    							 # e.g in a CVS tree, 'range' can be specified as a
    							 # function to call for each file:
    							 #'range'   => sub { return 
    							 #			($files->allreleases($LXR::Common::pathname),
    							 #			 $files->allrevisions($LXR::Common::pathname))
    							 #			}, # deferred function call.
    
    							 # The default version to display
    							 'default' => 'linux-2.6.6'},
    	 
    					 # Define typed variable "a".  First value is default.
    					 'a' => {'name'    => 'Architecture',
    							 'range'   => [qw(i386 alpha arm m68k mips ppc sparc sparc64)]},
    					},
    
      # These do funky things to paths in the system - you probably don't need them.
      'maps' => {
    			 '/include/asm[^\/]*/' => '/include/asm-$a/',
    			 '/arch/[^\/]+/'       => '/arch/$a/',
    			},
      
      
      # Templates used for headers and footers
      'htmlhead'		=> '/usr/local/lxr/http/html-head.html',
      'htmltail'		=> '/usr/local/lxr/http/html-tail.html',
      'htmldir'		    => '/usr/local/lxr/http/html-dir.html',
      'htmlident'       => '/usr/local/lxr/http/html-ident.html',
      'htmlident_refs'  => '/usr/local/lxr/http/html-ident-refs.html',
      
      'sourcehead'	=> '/usr/local/lxr/http/html-head.html',
      'sourcedirhead'	=> '/usr/local/lxr/http/html-head.html',
      'stylesheet'       => 'lxr.css',
      
      # sourceroot - where to get the source files from
    
      # For ordinary directories, this specifies a directory which has each version as a
      # subdirectory e.g.
      #  indexed-src/version1/...
      #  indexed-src/version2/...
      # The names of the version directories must match the values for the Version
      # variable above.
      'sourceroot'	=> '/usr/local/lxr/src',
      # Alternatively, this can specify a CVS repository by setting the value to "cvs:"
      # followed by the path to the repository.  Note this must be file accessible -
    remote
      # server access does NOT work.
      #     'sourceroot'	=> 'cvs:/hom/karsk/a/CVSROOT/linux',
    
      # The name to display for this source tree
      'sourcerootname'	=> 'Codes',
    
    
      # The DBI identifier for the database to use
      # For mysql, the format is dbi:mysql:dbname=<name>
      # for Postgres, it is dbi:Pg:dbname=<name>
      # for Oracle, it is dbi:Oracle:host=localhost;sid=DEVMMS;port=1521
      'dbname'		=> 'dbi:mysql:dbname=lxr',
    
      # If you need to specify the username or password for the database connection,
      # uncomment the following two lines
      #  'dbpass'		=> 'foo',
      #  'dbuser'		=> 'lxr',
    
      # For using glimpse, the directory to store the .glimpse files in is required
    #  'glimpsedir' => '/path/to/glimpse/databases',
    
      # Location of swish-e index database files if using swish-e
    #  'swishdir' => '/usr/local/lxr/src/$v',
    
      
      # where to look for include files inside the sourcetree.  This is used to hyperlink
      # to included files.
      'incprefix'	=> ['/include', '/include/linux'],
      
      # Which extensions to treat as images when browsing.  If a file is an image,
      # it is displayed.
      'graphicfile' => '(?i)\.(gif|jpg|jpeg|pjpg|pjpeg|xbm|png)$',  #'
    
      # How to map files to languages
      # Note that the string for the key and the first entry in the
      # array MUST match
      'filetype' => {
    				 # Format is
    				 # Language name, filepatten regexp, module to invoke,
                     # (optional )tabwidth
    				 # Note that to have another language supported by Generic.pm,
    				 # you must ensure that:
    				 # a) exuberant ctags supports it
    				 # b) generic.conf is updated to specify information about the language
    				 # c) the name of the language given here matches the entry in generic.conf
    				 'C' => ['C', '\.c$' #'
    				  , 'LXR::Lang::Generic', '8'],
    				 'C++' => ['C++',
    '\.C$|((?i)\.c\+\+$|\.cc$|\.cpp$|\.cxx$|\.h$|\.hh$|\.hpp$|\.hxx$|\.h\+\+$)' #'
    				  , 'LXR::Lang::Generic', '8'],
    
    # Some languages are commented out until the relevant entries in generic.conf are
    made
    # The list here is the set supported by ctags 5.0.1
    # 				 ['Beta', '(?i)\.bet$' #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['Cobol', '(?i)\.cob$'  #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['Eiffel', '(?i)\.e$'   #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['Fortran', '(?i)\.f$|\.for$|\.ftn$|\.f77$|\.f90$|\.f95$'   #'
    # 				  , 'LXR::Lang::Generic'],
    				 'Java' => ['Java', '(?i)\.java$'   #'
    				  , 'LXR::Lang::Java', '4'],
    # 				 ['Lisp', '(?i)\.cl$|\.clisp$|\.el$|\.l$|\.lisp$|\.lsp$|\.ml$'   #'
     # 				  , 'LXR::Lang::Generic'],
                      # No tabwidth specified here as an example
     				 'Make' => ['Make', '(?i)\.mak$|makefile*' #'
    							, 'LXR::Lang::Generic'],
    # 				 ['Pascal', '(?i)\.p$|\.pas$'   #'
    # 				  , 'LXR::Lang::Generic'],
    				 'Perl' => ['Perl', '(?i)\.pl$|\.pm$|\.perl$'   #'
    				  , 'LXR::Lang::Generic', '4'],
     				 'php' => ['php', '(?i)\.php$|\.php3$|\.phtml$'   #'
     				  , 'LXR::Lang::Generic', '2'],
    				 'Python' => ['Python', '(?i)\.py$|\.python$'   #'
    				  , 'LXR::Lang::Generic', '4'],
    # 				 ['rexx', '(?i)\.cmd$|\.rexx$|\.rx$'   #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['ruby', '(?i)\.rb$'   #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['scheme', '(?i)\.sch$|\.scheme$|\.scm$|\.sm$'   #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['shell', '(?i)\.sh$|\.bsh$|\.bash$|\.ksh$|\.zsh$'   #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['s-Lang', '(?i)\.sl$'   #'
    # 				  , 'LXR::Lang::Generic'],
    # 				 ['tcl', '(?i)\.tcl$|\.wish$'   #'
    # 				  , 'LXR::Lang::Generic'],
    				},
    
      # Maps interpreter names to languages.  The format is:
      #  regexp => langname
      #   regexp is matched against the part after #! on the first line of a file
      #   langname must match one of the keys in filetype above.
      #
      # This mapping is only used if the filename doesn't match a pattern above, so
      # a shell script called shell.c will be recognised as a C file, not a shell file.
      
      'interpreters' => {
    					 'perl' => 'Perl',
    #					 'bash' => 'shell',
    #					 'csh' => 'shell',
    					 'python' => 'Python',
    					},
      
    
    })
    


    LXR 0.9.3 版本已经发布, 安装过程比较方便 , 生成网页的脚本修正了
    不过安装前需要预先安装必须的工具(见附件MMagic)和glimpse最新版本
    安装过程和0.9.2 基本相同,不需要手工运行glimpse, 由lxr 自己调用.

  • 相关阅读:
    定时器Timer的使用
    Queue和BlockingQueue的使用以及使用BlockingQueue实现生产者-消费者
    ReentrantReadWriteLock读写锁的使用
    利用Lucene与Nutch构建简单的全文搜索引擎
    再见了,DM
    互联网公司高并发图片(缩略图)处理中间层服务架构设计一
    poj 3131 双向搜索+hash判重
    [置顶] linux常用命令大全
    堆排序
    iOS UIView非常用方法及属性详解
  • 原文地址:https://www.cnblogs.com/huqingyu/p/106006.html
Copyright © 2011-2022 走看看