安装配置 LXR

专业课学习操作系统,满心欢喜地以为可以是 Linux 代码导读,结果选用了一本八十年代的教材,介绍 UNIX v6 的。于是自己从图书馆借来了内核开发的入门读物《Linux 内核设计与实现》。既然是介绍内核的书,自然少不了代码,但是书中又不可能将每个提到的代码的相关信息全部写出来,这时就得自己去查看代码。查看代码的话,虽然 Linux 的代码可以很容易地得到,但那来看终归有些麻烦,各种调用需要查找半天。于是想起了很有名的一个网站 LXR,Linux 交叉引用。这个网站好是好,就是网络原因速度太慢,于是就想自己装一个。

先说一句,下面的安装环境都是64位 Gentoo。

最开始找到了 LXR Cross Referencer 这个项目,一看最后更新时间还挺新,看起来是一直都还在维护的。然后在 Gentoo 的网站上查到 LXR 是可以直接用 portage 安装的,于是安装,安装相关的包,最后放弃了。出于什么原因我也不记得了,最后一个原因肯定是不好看,肯定达不到上面那个网站的效果,所以就放弃了,到那个网站上去下载 LXR 分出来的版本 LXRng。(话说这个 ng 不会是表示 next generation 吧?)

安装支持库

首先从 LXR 的网站上用 git 把代码下载下来,

git clone git://lxr.linux.no/git/lxrng.git

然后我打开了里面的 INSTALL 文件,里面写着好多好多库。先说结论吧,在 Gentoo 的官方源里面,有两个库是没有的,分别是 Search-XapianCGI-Ajax,这两个最后安装。

最首要的是先安装 PostgreSQL,由于 LXR 是用 Perl 写成的,所以在 USE 里面加入了 Perl,然后安装。安装完成以后,安装 PostgreSQL 的 Perl 库 DBD-Pg。接下去安装 Cgi-SimpleHTML-ParserHTML-EntitiesTerm-ProgressBarDevel-SizeTemplate-Toolkit,这些都很容易,直接安装就可以了。(虽然我确定这些包的名称还费了些时间)

然后是 Apache 和它的 mod_perl,因为之前安装了,并没有太大困难,这里也不详述了。

最麻烦的问题来了,对于源里没有的 Search-XapianCGI-Ajax 怎么办呢?先把 Xapian 的主要部分给安装了吧。

安装 xapianxapian-bindings 这两个包。因为这两个包的最新版本对 amd64 平台都是 unstable 的,所以要在 /etc/portage/package.keywords 里面加入

=dev-libs/xapian-1.2.7-r1 ~amd64
=dev-libs/xapian-bindings-1.2.7-r2 ~amd64

(是的,在 Gentoo 的查询系统上显示,xapian 的 1.2.5 是稳定版本,我也曾经试图安装那个版本,然后仅安装非稳定版的 -bindings,但是之后安装的 Search-Xapian 还是会要求新的 1.2.7,所以就这样吧。另外一般状况下,最前面是写 >= 的,但是我出于个人喜好和完美主义,写了 =。)接下去直接安装这两个包即可。记得检查已经在 USE 里面加入了 perl

接下去安装那两个包。

Gentoo 有个很神奇的工具,也是我这次才发现的,叫做 g-cpan,可以把 CPAN 上面的包自动打包安装为 portage 的包。不过如果是第一次使用必须要先配置一下,在 /etc/make.conf 最后加上

ACCEPT_KEYWORDS="amd64"
PORTDIR_OVERLAY="/usr/local/portage"

(虽然这个配置看过去很简单,不过因为一开始忽略了这件事情,所以纠结了很长时间……)

接下去用 g-cpan 安装就可以了

sudo g-cpan -g CGI::Ajax Search::Xapian
sudo emerge CGI-Ajax Search-Xapian

至此需要安装的东西就已经全部装完了,下面进入第二阶段~

配置数据库

这个很简单了,不过在配置之前要先把自己将会用到的用户加入到 postgres 组里以保证可以访问。最重要的是要把之后的 apache 用户加入到 postgres 组里,否则后面会出现一些状况。

然后 supostgres 用户里,添加用户 root,并把 root 设置为管理员(因为之后生成的时候需要用到)

createuser root

然后创建 LXR 的数据库

createdb lxrng

大体上这样就没问题了。

调整配置文件并建立工作目录

我出于完美主义的原因,将 LXR 的工作目录放在了 /var/lib/lxrng 里面,如果你没有那些奇怪的癖好,完全可以直接在自己的文件夹下面放置这些东西。

首先要设置配置文件,将 LXR 根目录下的 lxrng.conf-dist 复制为 lxrng.conf,然后打开修改。里面大体上还是比较清晰的,如果只是要做一个 Linux 代码的交叉引用的话,大体上按照里面的配置,修改第10行

my $gitrepo = LXRng::Repo::Git
    ->new('/var/lib/lxrng/repos/linux-2.6/.git',
      release_re => qr/^v[^-]*$/,
      author_timestamp => 0);

里面的那个路径,使其指向你放置代码的 git 源(一般是代码文件夹下的 .git)。

如果你没有使用 git 来抓取代码,而是直接下载某个版本的代码,如 v3.1,可以放置到比如 /var/lib/lxrng/repos/linux/v3.1,那么这个部分就修改为

use LXRng::Repo::Plain;
$plainrepo = LXRng::Repo::Plain
    ->new('/var/lib/lxrng/repos/linux');

即可。(注意上面的 $gitrepo 在下面还有使用过一次,如果修改的话需要一并修改)

接下去是第19行

my $search  = LXRng::Search::Xapian->new('/var/lib/lxrng/text-db/linux-2.6');

需要在某个位置建立一个 text-db 文件夹,然后将上面的路径修改为你建立的那个文件夹的路径即可。同样的操作也发生在第29行

    # Must be writable by httpd user:
    'cache'       => '/var/lib/lxrng/cache',

注意这个文件夹需要对 apache:apache 可写。我的做法是把这个文件夹的组设置为 apache,然后设置权限为0775,当然也可以直接把所有者设置为 apache 然后保留原来权限。

注释掉下面这行

    'ctags_flags' => ["-I\@$LXRng::ROOT/lxr-ctags-quirks"],

不要问我为什么,这个我真不知道,总之如果部注释掉一会儿会出错。

最后是要生成引用的版本和默认显示的版本:

'ver_list' => [$gitrepo->allversions],

'ver_default' => 'v2.6.20.3',

我强烈建议你将 $gitrepo->allversions 修改为你想看的几个版本,甚至于只有一个版本也是没有问题的即使你有完整的历史记录,因为每个版本都需要生成很长时间,而且似乎过程很不稳定,如果没有特别的原因,最好不要生成太多版本。如果是不用 git 源的话,只要把你放在那个文件夹里的对应版本号填进去就可以了,最后修改默认显示的版本。

如果还想添加其他的代码,只要把代码最后 return 的大括号里面的部分复制一遍,根据需要修改就可以了。

初始化数据库及生成交叉引用

首先要添加一个符号链接

sudo ln -s /usr/bin/exuberants-ctags /usr/bin/ctags-exuberants

接下去没什么太大的差别,就是进入程序所在目录,然后

./lxr-db-admin linux --init
./lxr-genref linux

值得一说的是,这个过程非常非常非常漫长,在我的 i7 本上的虚拟机里,一跑至少三四个小时,而且看起来还很不稳定,不时会自动强制退出,而且退出以后可能会出现一些问题导致无法继续。这个问题比较严重,遇到这个问题如何解决放到之后的部分再来说吧。

配置 Apache

最后来配置 Apache。直接把文件夹下的 apache2-site.conf-dist-mod_perl 复制到 /etc/apache/vhosts.d/10_lxrng.conf,然后打开这个文件,将里面的所有 @@LXRROOT@@@@LXRURL@@ 根据自己的情况替换为相应的路径就可以了。然后重新启动 Apache

sudo /etc/rc.d/apache restart

问题解决

由于原来的版本在我这里基本上没什么希望能生成结束,所以我对这个程序做了一些修改,这个修改后的版本可以直接在我的 GitHub 上面找到:upsuper/lxrng。如果需要的话,可以不使用原来官方的代码而直接使用我修改过的代码。主要的差别有几点:一是消除了生成交叉引用时过大量的输出信息;二是增加了交叉引用生成时刷写 Xapian 索引的频率,以减少退出重做时可能出现的错误;三是修正了一些最后浏览时可能遇到的问题。

当然生成的时候还是可能会出错,这我也没办法。如果生成时被意外中断,重新执行又出现错误,可以将我修改的那个程序里面的 lxr-genref 第336行

    #warn("here $docid\n");

的注释符去掉,重新运行 lxr-genref,然后查看当程序报错时停止的那个编号,比如 12345。然后执行 psql lxrng 进入 lxrng 数据库,执行

DELETE FROM hashed_documents WHERE doc_id>=12345

然后再次执行 lxr-genref。这个过程可能反复一两次,直到不会报错位置。

如果用原始版本的话,最后在浏览的时候使用搜索,有可能会出现500错误以及无法显示出来的情况,如果出现,可以参考我做的修改。

后记

配置这个 LXR 真是折腾死我了,费了好大功夫,最后也总算是成功了。

另外真是很久很久没有在这里写东西了。也正因为这个过程实在太麻烦了,所以来写一写,权当一个记录。不过现在有 GitHub 这种东西,倒是好得多了。

参考文档

(貌似还有些别的参考资料,不记得是什么了……)

参考配置文件

最后最后贴一下自己的配置文件吧。配置文件里面声明了两个代码,一个是 Liunx 的,一个是 UNIX v6 的,Linux 是用 git,UNIX 是代码。程序全部放在 /var/lib/lxrng 里面,代码放在 /var/lig/lxrng/repos 里。

# -*- mode: perl -*-
# Configuration file
#
#

use LXRng::Index::PgBatch;
use LXRng::Repo::Git;
use LXRng::Repo::Plain;
use LXRng::Search::Xapian;

my $linuxrepo = LXRng::Repo::Git
    ->new('/var/lib/lxrng/repos/linux.git',
      release_re => qr/^v[^-]*$/,
      author_timestamp => 0);
my $unixrepo = LXRng::Repo::Plain
    ->new('/var/lib/lxrng/repos/unix');

my $index   = LXRng::Index::PgBatch->new(db_spec => 'dbname=lxrng;port=5432', 
                     db_user => "", db_pass => "",
                     # table_prefix => 'lxr'
                     );
my $search  = LXRng::Search::Xapian->new('/var/lib/lxrng/text-db');

return {
    'linux' => {
    'repository'  => $linuxrepo,
    'index'       => $index,
    'search'      => $search,

    'base_url'    => 'http://upsuper-gentoo/lxr',
    # Must be writable by httpd user:
    'cache'       => '/var/lib/lxrng/cache/linux',

    'fs_charset'  => 'iso-8859-1',
    # Tried successively
    'content_charset' => ['utf-8', 'iso-8859-1'],

    'languages'   => ['C', 'GnuAsm', 'Kconfig'],
    #'ctags_flags' => ["-I\@$LXRng::ROOT/lxr-ctags-quirks"],
    #'ver_list'    => [$gitrepo->allversions],
    'ver_list'    => ['v2.6.34', 'v3.0'],

    'ver_default' => 'v2.6.34',

    'include_maps' => 
        [
         [qr|^arch/(.*?)/|, qr|^asm/(.*)|,
          sub { "include/asm-$_[0]/$_[1]" }],
         [qr|^include/asm-(.*?)/|, qr|^asm/(.*)|,
          sub { "include/asm-$_[0]/$_[1]" }],
         [qr|^|, qr|^asm/(.*)|,
          sub { map { "include/asm-$_/$_[0]" }
            qw(i386 x86_64) }],
         [qr|^|, qr|(.*)|,
          sub { "include/$_[0]" }],
         ],
    },
    'unix' => {
    'repository'  => $unixrepo,
    'index'       => $index,
    'search'      => $search,

    'base_url'    => 'http://upsuper-gentoo/lxr',
    # Must be writable by httpd user:
    'cache'       => '/var/lib/lxrng/cache/unix',

    'fs_charset'  => 'iso-8859-1',
    # Tried successively
    'content_charset' => ['utf-8', 'iso-8859-1'],

    'languages'   => ['C', 'GnuAsm'],
    #'ctags_flags' => ["-I\@$LXRng::ROOT/lxr-ctags-quirks"],
    'ver_list'    => ['v6'],

    'ver_default' => 'v6',

    'include_maps' => 
        [
         [qr|^|, qr|(.*)|,
          sub { "sys/$_[0]" }],
         ],
    },
};

Comments !

social