maya's blog

About programming, aws and ubuntu

yum install時のprovides

yum install時のprovides

動機

rubyの mysql2 gem をインストールする際に libmysqlclient.so 等のライブラリが必要になる。 もしインストールしてない状態で gem install mysql2 するとエラーになり、下記の様なログが表示される。

$ gem install mysql2
Fetching: mysql2-0.5.2.gem (100%)
Building native extensions. This could take a while...
ERROR:  Error installing mysql2:
        ERROR: Failed to build gem native extension.

    current directory: /home/vagrant/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/mysql2-0.5.2/ext/mysql2
/home/vagrant/.rbenv/versions/2.5.0/bin/ruby -r ./siteconf20190820-7620-yq21vu.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
checking for -lmysqlclient... no
-----
mysql client is missing. You may need to 'apt-get install libmysqlclient-dev' or 'yum install mysql-devel', and try again.
-----
...省略

CentOSの場合はmysql-develyをyumでインストールしてねって親切にもエラーが表示される。

そこで yum install -y mysql-devel してインストールログを見るとmysql-devel パッケージでなく、mariadb-devel パッケージがインストールされていることに気づいた。

どうやって mysql-devel -> mariadb-devel がインストールされるんだろうと疑問に思ったので yum install 時の挙動を調べた。

yum install 時の挙動

$ man yum
...
install
...
       If  the  name is a file, then install works like localinstall. If the name doesn't match a package, then package "provides" are searched (e.g. "_sqlitecache.so()(64bit)") as are filelists (Eg. "/usr/bin/yum"). Also note
       that for filelists, wildcards will match multiple packages.

オンラインマニュアルにも書いてある通り、 yum install <name> で nameがパッケージ名と一致しなかったらrpmパッケージのprovidesが検索対象となる。

providesって何ってところで、yum provides サブコマンドを発見したのでオンラインマニュアルから抜粋

$ man yum
...
provides or whatprovides
       Is used to find out which package provides some feature or file. Just use a specific name or a file-glob-syntax wildcards to list the packages available or installed that provide that feature or file.
...

よくわからんので、コマンド叩いてみる

$ yum -q search mysql-devel
Warning: No matches found for: mysql-devel
$ yum -q provides mysql-devel
1:mariadb-devel-5.5.60-1.el7_5.i686 : Files for development of MariaDB/MySQL applications
Repo        : base
Matched from:
Provides    : mysql-devel = 1:5.5.60-1.el7_5



1:mariadb-devel-5.5.60-1.el7_5.x86_64 : Files for development of MariaDB/MySQL applications
Repo        : base
Matched from:
Provides    : mysql-devel = 1:5.5.60-1.el7_5

どうやらrpmパッケージのメタ情報に Provides という項目があり、 yum provides <name> 時に Provides 項目の値とnameが一致するrpmパッケージを表示している。 上記の場合は、yum provides mysql-devel で mariadb-devel rpmパッケージの Provides にmysql-develがあるので、mariadb_devel が引っかかっている。

なので yum install した際にパッケージ名で一致しなかったら rpmパッケージの Provides が検索される。 ってまぁ上記の yum install オンラインマニュアルに書いてあることそのまんまだった。

ちなみに、この provides サブコマンドでファイル名を指定することもできて、

$ yum -q provides /etc/hosts
setup-2.8.71-10.el7.noarch : A set of system configuration and setup files
Repo        : base
Matched from:
Filename    : /etc/hosts



setup-2.8.71-10.el7.noarch : A set of system configuration and setup files
Repo        : @anaconda
Matched from:
Filename    : /etc/hosts



$ yum -q provides hosts
$ yum -q provides ls
coreutils-8.22-23.el7.x86_64 : A set of basic GNU tools commonly used in shell scripts
Repo        : base
Matched from:
Filename    : /usr/bin/ls



coreutils-8.22-23.el7.x86_64 : A set of basic GNU tools commonly used in shell scripts
Repo        : @anaconda
Matched from:
Filename    : /usr/bin/ls

絶対パスで指定したりパスが通っているコマンドを指定すると、それらがどのrpmパッケージでインストールされたのかがわかる。 多分こっちの目的で provides サブコマンドを使うことのほうが多いんじゃないかな。

debian系だと dpkg -S コマンド相当かな。

$ dpkg -S /bin/ls
coreutils: /bin/ls

rpm コマンドでも --provides--whatprovides があるけど、yum provides とはちょっと挙動が違うのかな… パスの通ったファイル(コマンド)は検索してくれない。

$ rpm -q --provides mariadb-devel
package mariadb-devel is not installed
$ sudo yum install -y -q mysql-devel
$ rpm -q --provides mysql-devel
package mysql-devel is not installed
$ rpm -q --whatprovides mysql-devel
mariadb-devel-5.5.60-1.el7_5.x86_64
$ rpm -q --provides mariadb-devel
mariadb-devel = 1:5.5.60-1.el7_5
mariadb-devel(x86-64) = 1:5.5.60-1.el7_5
mysql-devel = 1:5.5.60-1.el7_5
mysql-devel(x86-64) = 1:5.5.60-1.el7_5
$ rpm -q --provides ls
package ls is not installed
$ rpm -q --whatprovides ls
no package provides ls
$ rpm -q --whatprovides /bin/ls
coreutils-8.22-23.el7.x86_64
$ rpm -qf /bin/ls
coreutils-8.22-23.el7.x86_64

他のパッケージマネージャで調べると、provides って単語自体が「そのファイルがどのパッケージからインストールされたものなのか」みたいなことを表しているぽい。

まとめ

  • rpm の provides という機能でパッケージにaliasのようなものを設定できるため yum install mysql-develmariadb-devel がインストールされる
  • yum provides コマンドで指定したファイル、コマンドがどのrpmパッケージでインストールされたのか調べることができる

参照