利用GNU stow工具管理源代码安装的程序

经常使用Linux工作的人都知道,在Linux上安装程序方法有很多,一般来说相应的Linux发行版都有自己的包管理程序,可以统一管理程序,例如Ubuntu下的apt-get或者CentOS下的yum。但是有时候一些程序必须由源代码编译进行安装,例如:

  • 安装源中的程序版本过低,而我们需要使用最新的版本;
  • 包管理器中根本不存在相应的程序,这时候我们没有其他选择;
  • 有时候可以使用提前预编译好的程序,不过也会出现兼容性的问题;
  • 有我们要定制一些程序,那么只能从源头编译做起。

以上种种都说明从源代码编译安装程序都是日常工作中不可忽略的工作。

我们都知道一般由源代码安装程序时候,如果不对configure文件做配置,编译好的程序默认安装在/usr/local下面。其实这种方法存在几个缺陷:

  1. 当我们安装了很多程序时,/usr/local下面的子目录例如binlibdoc中会有一堆东西,你无法精确的分辨哪些程序是属于哪个源代码编译的,这在删除程序时就会很不方便。
  2. 如果/usr/local中已经存在了某个程序,安装新程序时如果出现冲突,会比较难办,你无法确定究竟以那个版本为准而保证两个程序都不受影响正常运行。

所以我一直在寻找能够对源代码安装的程序进行管理的方法。这几天在网上看到了其实GNU已经帮我们开发了这个东西,那就是GNU stow,通过这几天使用发现真的很好用,不但能管理程序,还能管理/home路径下的.隐藏配置文件。但不知道为什么网上资料貌似不是很多,所以在这里分享一下。

简单原理

其实stow的原理很简单,就是将你指定的安装目录中的程序,通过建立软连接的方式映射到系统常用程序路径例如/usr/local

说来也很巧,在不知道stow之前,我就是用类似的方式来管理我主目录下各种.配置文件的。例如我经常使用的.vimrc.zshrc.bashrc文件。先在你喜欢的地方建立一个目录例如WorkConfig,然后建立硬连接

1
2
3
ln    ~/.vimrc      ~/WorkConfig/vim_config
ln ~/.zshrc ~/WorkConfig/zsh_config
ln ~/.bashrc ~/WorkConfig/bash_config

以后我们更改其中这三个配置文件时,WorkConfig文件夹中对应的文件也会跟着变化。这样我们就很方便的可以管理WorkConfig这个文件夹,比如提交到Github

1
2
3
cd ~/WorkConfig
git init
... ...

stow的管理方式其实跟这类似。但不过更规范,更灵活。

使用stow

先在发行版中安装stow,一般的包管理中都有这个程序,可以直接安装。在Ubuntu中,可以使用

1
sudo apt-get install stow

然后就可以使用了。

这里以使用源代码方式来安装ruby为例。来演示stow的使用。

编译安装ruby

首先在一个你喜欢的目录中建立stow文件夹。我是将文件夹建在/usr/local下面了。

1
2
user@host$ ls /usr/local
bin etc games include lib man sbin share src stow

同时进入stow文件夹下建立一个文件夹ruby

下面就可以正常地从源代码编译安装ruby了。

其实Ubuntu的包管理中含有ruby,不过这里就出现我上面说的问题了。包管理器中的ruby版本很低,我是要安装Jekyll 3.0的版本,要求ruby必须大于2.0。不得已只能从源代码编译安装。

在做编译配置时,注意选择安装路径

1
2
3
./configure --prefix=/usr/local/stow/ruby  #就是上面你建立在stow路径下的ruby目录
make
sudo make install

熟悉的人都知道这其实是将程序安装在自定义路径下。
下面查看/usr/local/stow/ruby

1
2
user@host$ ls /usr/local/stow/ 
bin include lib share

这里可以看到目录结构跟/usr/local下面是一样的。

使用stow进行映射

进入/usr/local/stow/目录下执行sudo stow ruby,stow就会将ruby下的目录以及目录下的文件以对应的方式映射到/usr/local下面,例如ruby/bin目录下存在以下文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-rwxr-xr-x 1 root root     4854  3月  4 11:15 erb
-rwxr-xr-x 1 root root 558 3月 4 11:15 gem
-rwxr-xr-x 1 root root 202 3月 4 11:15 irb
-rwxr-xr-x 1 root root 507 3月 4 14:13 jekyll
-rwxr-xr-x 1 root root 515 3月 4 14:09 kramdown
-rwxr-xr-x 1 root root 507 3月 4 14:09 listen
-rwxr-xr-x 1 root root 499 3月 4 11:15 rake
-rwxr-xr-x 1 root root 950 3月 4 11:15 rdoc
-rwxr-xr-x 1 root root 200 3月 4 11:15 ri
-rwxr-xr-x 1 root root 505 3月 4 14:08 rougify
-rwxr-xr-x 1 root root 15203908 3月 4 11:11 ruby
-rwxr-xr-x 1 root root 519 3月 4 14:08 safe_yaml
-rwxr-xr-x 1 root root 499 3月 4 14:09 sass
-rwxr-xr-x 1 root root 507 3月 4 14:09 sass-convert
-rwxr-xr-x 1 root root 499 3月 4 14:09 scss

那么执行完命令以后,/usr/local/bin下面就会存在上面程序的软连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-rwxr-xr-x 1 root root  460  2月  3 00:06 bundle
-rwxr-xr-x 1 root root 461 2月 3 00:06 bundler
lrwxrwxrwx 1 root root 20 3月 4 11:21 erb -> ../stow/ruby/bin/erb
-rwxr-xr-x 1 root root 212 3月 7 01:38 fab
lrwxrwxrwx 1 root root 20 3月 4 11:21 gem -> ../stow/ruby/bin/gem
lrwxrwxrwx 1 root root 20 3月 4 11:21 irb -> ../stow/ruby/bin/irb
lrwxrwxrwx 1 root root 23 3月 4 14:39 jekyll -> ../stow/ruby/bin/jekyll
lrwxrwxrwx 1 root root 25 3月 4 14:39 kramdown -> ../stow/ruby/bin/kramdown
lrwxrwxrwx 1 root root 23 3月 4 14:39 listen -> ../stow/ruby/bin/listen
-rwxr-xr-x 1 root root 2774 3月 7 01:38 pnuke
-rwxr-xr-x 1 root root 3913 3月 7 01:38 prsync
-rwxr-xr-x 1 root root 3234 3月 7 01:38 pscp
-rwxr-xr-x 1 root root 4026 3月 7 01:38 pslurp
-rwxr-xr-x 1 root root 3850 3月 7 01:38 pssh
-rwxr-xr-x 1 root root 266 3月 7 01:38 pssh-askpass
lrwxrwxrwx 1 root root 21 3月 4 11:21 rake -> ../stow/ruby/bin/rake
lrwxrwxrwx 1 root root 21 3月 4 11:21 rdoc -> ../stow/ruby/bin/rdoc
lrwxrwxrwx 1 root root 19 3月 4 11:21 ri -> ../stow/ruby/bin/ri
lrwxrwxrwx 1 root root 24 3月 4 14:39 rougify -> ../stow/ruby/bin/rougify
lrwxrwxrwx 1 root root 21 3月 4 11:21 ruby -> ../stow/ruby/bin/ruby
lrwxrwxrwx 1 root root 26 3月 4 14:39 safe_yaml -> ../stow/ruby/bin/safe_yaml
lrwxrwxrwx 1 root root 21 3月 4 14:39 sass -> ../stow/ruby/bin/sass
lrwxrwxrwx 1 root root 29 3月 4 14:39 sass-convert -> ../stow/ruby/bin/sass-convert
lrwxrwxrwx 1 root root 21 3月 4 14:39 scss -> ../stow/ruby/bin/scss

这样就相当于新安装的软件也存在于系统默认的环境里了。直接使用即可,很方便。

当我们删除安装包时就变得简单了,首先使用stow --delete ruby删除/usr/local建好的软连接,然后直接删除stow下的ruby文件夹即可。

注意

  • stow默认的配置都会将软连接建立在/usr/local下面,当然我们可以更改,具体更改方法可以参看stow的官方文档
  • 一旦我们要映射的路径中存在同名的文件,stow程序会报错,有利于我们来进行选择

这就是用stow来管理由源代码编译安装的程序使用方法,正如前面所说,stow也可以用来管理.配置文件。这里便不说明了,可以参看官方文档或者Google。

参考文档