アシアルの中の人が技術と思いのたけをつづるブログ

VIM-ShellのRPMを作ってみました

タグ [  Tech  Vim  RPM  Linux  ]
最近社内のVim使いの方々の間で、VIM-Shellというパッチが話題になっています。これはVimのなかでシェルを実行できるというもので、EmacsのシェルモードがVimにも欲しいねという話が発端です。
Vim&CentOSの環境で開発している人が多いこともあり、どうせならとRPMパッケージを作ってみました。

まずは、RPMを作成するために必要なものをインストールします。今回はひとつひとつ入れていきますが、面倒な場合やビルド専用マシンにする場合などは、開発ツールや開発ライブラリを次のようにまとめてインストールしておくと楽かと思います。

  1. # yum grouplist
  2. # yum groupinstall "Development Tools"
  3. # yum groupinstall "Development Libraries"

まずは、何は無くともrpmbuildコマンドが必要ですので、インストールします。

  1. # yum install rpm-build

SRPMを取得するためにyumdownloaderコマンドを使いますので、インストールします。

  1. # yum install yum-utils

yumdownloaderコマンドでSRPMを取得するためのリポジトリを設定します。一から書くのは面倒ですので /etc/yum.repos.d/CentOS-Base.repo をコピーして書き換えます。

  1. # cd /etc/yum.repos.d/
  2. # cp CentOS-Base.repo CentOS-Source.repo
  3. # vi CentOS-Source.repo

baseurlを近くのミラーサイトにします。また、普段は見に行く必要はありませんので「enabled=0」にしておきます。

  1. # CentOS-Source.repo
  2. [base-source]
  3. name=CentOS-$releasever - Base Source
  4. baseurl=http://ftp.riken.jp/Linux/centos/$releasever/os/SRPMS/
  5. gpgcheck=1
  6. enabled=0
  7. gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
  8. #released updates
  9. [updates-source]
  10. name=CentOS-$releasever - Updates Source
  11. baseurl=http://ftp.riken.jp/Linux/centos/$releasever/updates/SRPMS/
  12. gpgcheck=1
  13. enabled=0
  14. gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
  15. #packages used/produced in the build but not released
  16. [addons-source]
  17. name=CentOS-$releasever - Addons Source
  18. baseurl=http://ftp.riken.jp/Linux/centos/$releasever/addons/SRPMS/
  19. gpgcheck=1
  20. enabled=0
  21. gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
  22. #additional packages that may be useful
  23. [extras-source]
  24. name=CentOS-$releasever - Extras Source
  25. baseurl=http://ftp.riken.jp/Linux/centos/$releasever/extras/SRPMS/
  26. gpgcheck=1
  27. enabled=0
  28. gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
  29. #additional packages that extend functionality of existing packages
  30. [centosplus-source]
  31. name=CentOS-$releasever - Plus Source
  32. baseurl=http://ftp.riken.jp/Linux/centos/$releasever/centosplus/SRPMS/
  33. gpgcheck=1
  34. enabled=0
  35. gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
  36. #contrib - packages by Centos Users
  37. [contrib-source]
  38. name=CentOS-$releasever - Contrib Source
  39. baseurl=http://ftp.riken.jp/Linux/centos/$releasever/contrib/SRPMS/
  40. gpgcheck=1
  41. enabled=0
  42. gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5

次に、一般ユーザでRPMを作成するための設定をします。RPMの作成をrootで行うと、SPECファイルの記述ミスや操作ミスなどで環境を破壊する恐れがあるためです。

以下、一般ユーザーで作業を行います。

  1. $ mkdir -p ~/rpm/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
  2. $ echo "%_topdir $HOME/rpm" >> ~/.rpmmacros

これで、HOMEのrpmディレクトリがRPM作成の作業場になります。

さて、準備が整いましたので、Vimのカスタムパッケージ作りに入ります。
まずは、インストールされているVimのバージョンを調べます。

  1. $ yum list installed | grep vim
  2. vim-common.i386                          2:7.0.109-3.el5.3      installed
  3. vim-enhanced.i386                        2:7.0.109-3.el5.3      installed
  4. vim-minimal.i386                         2:7.0.109-3.el5.3      installed

次にパッケージを提供しているリポジトリを調べます。

  1. $ yum search vim | grep vim-common.i386
  2. vim-common.i386                          2:7.0.109-3            base
  3. vim-common.i386                          2:7.0.109-3.el5.3      updates
  4. vim-common.i386                          2:7.0.109-3.el5.3      installed

先ほど調べたバージョンのパッケージは、updatesリポジトリのようですね。では、updatesからSRPMを取得します。

  1. $ yumdownloader --enablerepo=updates-source --source vim

カレントディレクトリに vim-7.0.109-3.el5.3.src.rpm がダウンロードされましたので、これをインストールします。

  1. $ rpm -ivh vim-7.0.109-3.el5.3.src.rpm

VIM-Shellのパッチをダウンロードして、SOURCEディレクトリへ入れます。

  1. $ cd ~/rpm/SOURCES/
  2. $ wget http://www.wana.at/vimshell/vimshell_1.0_vim7.0.patch.bz2

SPECファイルを修正します。

1. Releaseの末尾にVIM-Shellリリース1の意味で「vs1」を追加
2. Patch行の最後にVIM-Shellのパッチファイルを追加
3. %prep部の後半へVIM-Shellパッチの実行処理を追加
4. %changelog部へ変更履歴を追加

  1. Summary: The VIM editor.
  2. Name: vim
  3. Version: %{baseversion}.%{beta}%{patchlevel}
  4. Release: 3%{?dist}.3vs1
  5. License: freeware
  6. Group: Applications/Editors
  7. Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}%{?beta}%{?CVSDATE}.tar.bz2

  1. Patch3100: vim-selinux.patch
  2. Patch3101: vim-selinux2.patch
  3. # VIM-Shell
  4. Patch9000: http://www.wana.at/vimshell/vimshell_1.0_vim7.0.patch.bz2
  5. Buildroot: %{_tmppath}/%{name}-%{version}-root

  1. %patch3101 -p1
  2. %endif
  3. # VIM-Shell
  4. %patch9000 -p0
  5. %if "%{withcvim}" == "1"
  6. mkdir cvim

  1. %changelog
  2. * Mon Nov 26 2007 Your Name <mail@example.com> 7.0.109-3.3vs1
  3. - add VIM-Shell 1.0

それではビルドします。折角なので、アーキテクチャにi686を指定します。また、リリース番号を揃えるためにdist定義を付与します。

  1. $ rpmbuild -ba --target i686 --define 'dist .el5' ~/rpm/SPECS/vim.spec
  2. ビルド対象プラットフォーム: i686
  3. ターゲット i686 用にビルド中
  4. エラー: ビルド依存性の失敗:
  5.         python-devel は vim-7.0.109-3.3.i386 に必要とされています
  6.         libtermcap-devel は vim-7.0.109-3.3.i386 に必要とされています
  7.         libacl-devel は vim-7.0.109-3.3.i386 に必要とされています
  8.         gpm-devel は vim-7.0.109-3.3.i386 に必要とされています
  9.         autoconf は vim-7.0.109-3.3.i386 に必要とされています
  10.         libselinux-devel は vim-7.0.109-3.3.i386 に必要とされています
  11.         gtk2-devel は vim-7.0.109-3.3.i386 に必要とされています
  12.         libSM-devel は vim-7.0.109-3.3.i386 に必要とされています
  13.         libXt-devel は vim-7.0.109-3.3.i386 に必要とされています
  14.         libXpm-devel は vim-7.0.109-3.3.i386 に必要とされています

gccと表示された必要なものをインストールします。

  1. $ sudo yum install gcc python-devel libtermcap-devel libacl-devel gpm-devel autoconf libselinux-devel gtk2-devel libSM-devel libXt-devel libXpm-devel

再度rpmbuildコマンドを実行します。無事コンパイルまでいったようですが、エラーで止まってしまいました。

  1. gui.c: In function ‘gui_start’:
  2. gui.c:142: 警告: ignoring return value of ‘read’, declared with attribute warn_unused_result
  3. gui.c:2423:2: error: #endif に #if がありません
  4. make: *** [objects/gui.o] エラー 1

VIM-Shellのパッチが src/gui.c に不要と思われる「#endif」を挿入しているようですので、これを削除するパッチを作成します。

  1. $ cd ~/rpm/BUILD/vim70/
  2. $ cp src/gui.c src/gui.c~
  3. $ vi src/gui.c
  4. $ diff -u src/gui.c~ src/gui.c > ~/rpm/SOURCES/vimshell_1.0_vim7.0-gui.patch

  1. --- src/gui.c~  2007-11-22 22:47:18.000000000 +0900
  2. +++ src/gui.c   2007-11-22 22:53:47.000000000 +0900
  3. @@ -2420,7 +2420,6 @@
  4.      long_u     old_hl_mask;
  5.      int                off;
  6.      sattr_T    first_attr;
  7. -#endif
  8.      int                idx, len;
  9.      int                back, nback;
  10.      int                retval = FALSE;

では、このパッチをSPECファイルに追加します。

  1. Patch3100: vim-selinux.patch
  2. Patch3101: vim-selinux2.patch
  3. # VIM-Shell
  4. Patch9000: http://www.wana.at/vimshell/vimshell_1.0_vim7.0.patch.bz2
  5. Patch9001: vimshell_1.0_vim7.0-gui.patch
  6. Buildroot: %{_tmppath}/%{name}-%{version}-root

  1. %patch3101 -p1
  2. %endif
  3. # VIM-Shell
  4. %patch9000 -p0
  5. %patch9001 -p0
  6. %if "%{withcvim}" == "1"
  7. mkdir cvim

再度rpmbuildコマンドを実行します。またもやコンパイルエラーです。

  1. gcc -c -I. -Iproto -DHAVE_CONFIG_H     -g -O2         -o objects/vim_shell.o vim_shell.c
  2. vim_shell.c:120: error: expected ‘)’ before ‘width’
  3. vim_shell.c: In function ‘vim_shell_start’:
  4. vim_shell.c:229: error: 不完全型のポインタへの間接参照
  5. vim_shell.c:230: error: 不完全型のポインタへの間接参照
  6. vim_shell.c:237: error: 不完全型のポインタへの間接参照
  7. vim_shell.c:237: error: 不完全型のポインタへの間接参照
  8. vim_shell.c:238: error: 不完全型のポインタへの間接参照

~/rpm/BUILD/vim70/src/feature.h を見てみると、

  1. #if defined(FEAT_NORMAL) && (defined(UNIX) || defined(MACOS_X))
  2. #define FEAT_VIMSHELL
  3. #endif

となっているので「--with-features=tiny」の場合はエラーになるようです。
対処法はいろいろあると思いますが、今回は src/vim_shell.c と src/terminal.c の中身を「FEAT_VIMSHELL」が未定義の場合はコメントアウトするようにしてみます。

  1. $ diff -u src/vim_shell.c~ src/vim_shell.c > ~/rpm/SOURCES/vimshell_1.0_vim7.0-feature.patch
  2. $ diff -u src/terminal.c~ src/terminal.c >> ~/rpm/SOURCES/vimshell_1.0_vim7.0-feature.patch

  1. --- src/vim_shell.c~    2007-11-22 22:55:56.000000000 +0900
  2. +++ src/vim_shell.c     2007-11-22 23:08:08.000000000 +0900
  3. @@ -16,6 +16,7 @@
  4.  #include "vim.h"
  5. +#ifdef FEAT_VIMSHELL
  6.  #include <errno.h>
  7.  #include <stdlib.h>
  8.  #include <string.h>
  9. @@ -908,3 +909,4 @@
  10.         return rval;
  11.  }
  12. +#endif
  13. --- src/terminal.c~     2007-11-22 22:55:56.000000000 +0900
  14. +++ src/terminal.c      2007-11-22 23:08:08.000000000 +0900
  15. @@ -32,6 +32,7 @@
  16.  #include "vim.h"
  17. +#ifdef FEAT_VIMSHELL
  18.  #ifdef VIMSHELL_DEBUG
  19.  #  define ESCDEBUG
  20.  /*
  21. @@ -1929,3 +1930,4 @@
  22.         return written;
  23.  }
  24. +#endif

作成したパッチをSPECファイルへ追加します。

  1. Patch3100: vim-selinux.patch
  2. Patch3101: vim-selinux2.patch
  3. # VIM-Shell
  4. Patch9000: http://www.wana.at/vimshell/vimshell_1.0_vim7.0.patch.bz2
  5. Patch9001: vimshell_1.0_vim7.0-gui.patch
  6. Patch9002: vimshell_1.0_vim7.0-feature.patch
  7. Buildroot: %{_tmppath}/%{name}-%{version}-root

  1. %patch3101 -p1
  2. %endif
  3. # VIM-Shell
  4. %patch9000 -p0
  5. %patch9001 -p0
  6. %patch9002 -p0
  7. %if "%{withcvim}" == "1"
  8. mkdir cvim

再度rpmbuildコマンドを実行します。今度こそー!

……。

…………。

………………。

できたー!

早速インストールして、使ってみます。

  1. $ cd ~/rpm/RPMS/i686/
  2. $ sudo rpm -Uvh vim-common-7.0.109-3.el5.3vs1.i686.rpm vim-enhanced-7.0.109-3.el5.3vs1.i686.rpm vim-minimal-7.0.109-3.el5.3vs1.i686.rpm

Vimを起動して「:vimshell」を実行します。おー、Vimの中でシェルが動く!

といった感じで、CentOS5用のカスタムVimパッケージができあがりました。RPMパッケージは作らずに、ソースから「./configure;make;make install」でもいいのですが、同じ環境が複数ある場合は、やはりパッケージを作ったほうが便利かと思われます。

まぁ、私が普段使うエディタはEmacsですので、このパッケージを使うことはほぼないのですが……。

トラックバック