最近社内のVim使いの方々の間で、VIM-Shellというパッチが話題になっています。これはVimのなかでシェルを実行できるというもので、EmacsのシェルモードがVimにも欲しいねという話が発端です。
Vim&CentOSの環境で開発している人が多いこともあり、どうせならとRPMパッケージを作ってみました。
まずは、RPMを作成するために必要なものをインストールします。今回はひとつひとつ入れていきますが、面倒な場合やビルド専用マシンにする場合などは、開発ツールや開発ライブラリを次のようにまとめてインストールしておくと楽かと思います。
# yum grouplist
# yum groupinstall "Development Tools"
# yum groupinstall "Development Libraries"
まずは、何は無くともrpmbuildコマンドが必要ですので、インストールします。
# yum install rpm-build
SRPMを取得するためにyumdownloaderコマンドを使いますので、インストールします。
# yum install yum-utils
yumdownloaderコマンドでSRPMを取得するためのリポジトリを設定します。一から書くのは面倒ですので /etc/yum.repos.d/CentOS-Base.repo をコピーして書き換えます。
# cd /etc/yum.repos.d/
# cp CentOS-Base.repo CentOS-Source.repo
# vi CentOS-Source.repo
baseurlを近くのミラーサイトにします。また、普段は見に行く必要はありませんので「enabled=0」にしておきます。
# CentOS-Source.repo
[base-source]
name=CentOS-$releasever - Base Source
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/os/SRPMS/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
#released updates
[updates-source]
name=CentOS-$releasever - Updates Source
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/updates/SRPMS/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
#packages used/produced in the build but not released
[addons-source]
name=CentOS-$releasever - Addons Source
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/addons/SRPMS/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
#additional packages that may be useful
[extras-source]
name=CentOS-$releasever - Extras Source
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/extras/SRPMS/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
#additional packages that extend functionality of existing packages
[centosplus-source]
name=CentOS-$releasever - Plus Source
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/centosplus/SRPMS/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
#contrib - packages by Centos Users
[contrib-source]
name=CentOS-$releasever - Contrib Source
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/contrib/SRPMS/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5
次に、一般ユーザでRPMを作成するための設定をします。RPMの作成をrootで行うと、SPECファイルの記述ミスや操作ミスなどで環境を破壊する恐れがあるためです。
以下、一般ユーザーで作業を行います。
$ mkdir -p ~/rpm/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
$ echo "%_topdir $HOME/rpm" >> ~/.rpmmacros
これで、HOMEのrpmディレクトリがRPM作成の作業場になります。
さて、準備が整いましたので、Vimのカスタムパッケージ作りに入ります。
まずは、インストールされているVimのバージョンを調べます。
$ yum list installed | grep vim
vim-common.i386 2:7.0.109-3.el5.3 installed
vim-enhanced.i386 2:7.0.109-3.el5.3 installed
vim-minimal.i386 2:7.0.109-3.el5.3 installed
次にパッケージを提供しているリポジトリを調べます。
$ yum search vim | grep vim-common.i386
vim-common.i386 2:7.0.109-3 base
vim-common.i386 2:7.0.109-3.el5.3 updates
vim-common.i386 2:7.0.109-3.el5.3 installed
先ほど調べたバージョンのパッケージは、updatesリポジトリのようですね。では、updatesからSRPMを取得します。
$ yumdownloader --enablerepo=updates-source --source vim
カレントディレクトリに vim-7.0.109-3.el5.3.src.rpm がダウンロードされましたので、これをインストールします。
$ rpm -ivh vim-7.0.109-3.el5.3.src.rpm
VIM-Shellのパッチをダウンロードして、SOURCEディレクトリへ入れます。
$ cd ~/rpm/SOURCES/
$ 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部へ変更履歴を追加
Summary: The VIM editor.
Name: vim
Version: %{baseversion}.%{beta}%{patchlevel}
Release: 3%{?dist}.3<strong>vs1</strong>
License: freeware
Group: Applications/Editors
Source0: ftp://ftp.vim.org/pub/vim/unix/vim-%{baseversion}%{?beta}%{?CVSDATE}.tar.bz2
Patch3100: vim-selinux.patch
Patch3101: vim-selinux2.patch
<strong># VIM-Shell</strong>
<strong>Patch9000: http://www.wana.at/vimshell/vimshell_1.0_vim7.0.patch.bz2</strong>
Buildroot: %{_tmppath}/%{name}-%{version}-root
%patch3101 -p1
%endif
<strong># VIM-Shell</strong>
<strong>%patch9000 -p0</strong>
%if "%{withcvim}" == "1"
mkdir cvim
%changelog
<strong>* Mon Nov 26 2007 Your Name <mail@example.com> 7.0.109-3.3vs1</strong>
<strong>- add VIM-Shell 1.0</strong>
それではビルドします。折角なので、アーキテクチャにi686を指定します。また、リリース番号を揃えるためにdist定義を付与します。
$ rpmbuild -ba --target i686 --define 'dist .el5' ~/rpm/SPECS/vim.spec
ビルド対象プラットフォーム: i686
ターゲット i686 用にビルド中
エラー: ビルド依存性の失敗:
python-devel は vim-7.0.109-3.3.i386 に必要とされています
libtermcap-devel は vim-7.0.109-3.3.i386 に必要とされています
libacl-devel は vim-7.0.109-3.3.i386 に必要とされています
gpm-devel は vim-7.0.109-3.3.i386 に必要とされています
autoconf は vim-7.0.109-3.3.i386 に必要とされています
libselinux-devel は vim-7.0.109-3.3.i386 に必要とされています
gtk2-devel は vim-7.0.109-3.3.i386 に必要とされています
libSM-devel は vim-7.0.109-3.3.i386 に必要とされています
libXt-devel は vim-7.0.109-3.3.i386 に必要とされています
libXpm-devel は vim-7.0.109-3.3.i386 に必要とされています
gccと表示された必要なものをインストールします。
$ sudo yum install gcc python-devel libtermcap-devel libacl-devel gpm-devel autoconf libselinux-devel gtk2-devel libSM-devel libXt-devel libXpm-devel
再度rpmbuildコマンドを実行します。無事コンパイルまでいったようですが、エラーで止まってしまいました。
gui.c: In function ‘gui_start’:
gui.c:142: 警告: ignoring return value of ‘read’, declared with attribute warn_unused_result
gui.c:2423:2: error: #endif に #if がありません
make: *** [objects/gui.o] エラー 1
VIM-Shellのパッチが src/gui.c に不要と思われる「#endif」を挿入しているようですので、これを削除するパッチを作成します。
$ cd ~/rpm/BUILD/vim70/
$ cp src/gui.c src/gui.c~
$ vi src/gui.c
$ diff -u src/gui.c~ src/gui.c > ~/rpm/SOURCES/vimshell_1.0_vim7.0-gui.patch
--- src/gui.c~ 2007-11-22 22:47:18.000000000 +0900
+++ src/gui.c 2007-11-22 22:53:47.000000000 +0900
@@ -2420,7 +2420,6 @@
long_u old_hl_mask;
int off;
sattr_T first_attr;
-#endif
int idx, len;
int back, nback;
int retval = FALSE;
では、このパッチをSPECファイルに追加します。
Patch3100: vim-selinux.patch
Patch3101: vim-selinux2.patch
# VIM-Shell
Patch9000: http://www.wana.at/vimshell/vimshell_1.0_vim7.0.patch.bz2
<strong>Patch9001: vimshell_1.0_vim7.0-gui.patch</strong>
Buildroot: %{_tmppath}/%{name}-%{version}-root
%patch3101 -p1
%endif
# VIM-Shell
%patch9000 -p0
<strong>%patch9001 -p0</strong>
%if "%{withcvim}" == "1"
mkdir cvim
再度rpmbuildコマンドを実行します。またもやコンパイルエラーです。
gcc -c -I. -Iproto -DHAVE_CONFIG_H -g -O2 -o objects/vim_shell.o vim_shell.c
vim_shell.c:120: error: expected ‘)’ before ‘width’
vim_shell.c: In function ‘vim_shell_start’:
vim_shell.c:229: error: 不完全型のポインタへの間接参照
vim_shell.c:230: error: 不完全型のポインタへの間接参照
vim_shell.c:237: error: 不完全型のポインタへの間接参照
vim_shell.c:237: error: 不完全型のポインタへの間接参照
vim_shell.c:238: error: 不完全型のポインタへの間接参照
~/rpm/BUILD/vim70/src/feature.h を見てみると、
#if defined(FEAT_NORMAL) & & (defined(UNIX) || defined(MACOS_X))
#define FEAT_VIMSHELL
#endif
となっているので「--with-features=tiny」の場合はエラーになるようです。
対処法はいろいろあると思いますが、今回は src/vim_shell.c と src/terminal.c の中身を「FEAT_VIMSHELL」が未定義の場合はコメントアウトするようにしてみます。
$ diff -u src/vim_shell.c~ src/vim_shell.c > ~/rpm/SOURCES/vimshell_1.0_vim7.0-feature.patch
$ diff -u src/terminal.c~ src/terminal.c >> ~/rpm/SOURCES/vimshell_1.0_vim7.0-feature.patch
--- src/vim_shell.c~ 2007-11-22 22:55:56.000000000 +0900
+++ src/vim_shell.c 2007-11-22 23:08:08.000000000 +0900
@@ -16,6 +16,7 @@
#include "vim.h"
+#ifdef FEAT_VIMSHELL
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -908,3 +909,4 @@
return rval;
}
+#endif
--- src/terminal.c~ 2007-11-22 22:55:56.000000000 +0900
+++ src/terminal.c 2007-11-22 23:08:08.000000000 +0900
@@ -32,6 +32,7 @@
#include "vim.h"
+#ifdef FEAT_VIMSHELL
#ifdef VIMSHELL_DEBUG
# define ESCDEBUG
/*
@@ -1929,3 +1930,4 @@
return written;
}
+#endif
作成したパッチをSPECファイルへ追加します。
Patch3100: vim-selinux.patch
Patch3101: vim-selinux2.patch
# VIM-Shell
Patch9000: http://www.wana.at/vimshell/vimshell_1.0_vim7.0.patch.bz2
Patch9001: vimshell_1.0_vim7.0-gui.patch
<strong>Patch9002: vimshell_1.0_vim7.0-feature.patch</strong>
Buildroot: %{_tmppath}/%{name}-%{version}-root
%patch3101 -p1
%endif
# VIM-Shell
%patch9000 -p0
%patch9001 -p0
<strong>%patch9002 -p0</strong>
%if "%{withcvim}" == "1"
mkdir cvim
再度rpmbuildコマンドを実行します。今度こそー!
……。
…………。
………………。
できたー!
早速インストールして、使ってみます。
$ cd ~/rpm/RPMS/i686/
$ 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ですので、このパッケージを使うことはほぼないのですが……。