Edited at

RustのソフトウェアをSnapcraftのパッケージにする


はじめに

SnapcraftとはCanonicalが開発しているパッケージマネージャです。(昔はSnappyだったと思うんですが変わったんですかね?公式サイトがSnapcraftになっているのでここではそれに従います)

最近のUbuntuにはデフォルトで入っていたり、いろいろなlinuxディストリビューションに対応したりしているようです。

Rustのソフトウェアを配布する際に、Rustの開発者前提ならcargo installでいいのですが、一般には敷居が高いです。

そうすると「yumaptといった普通のパッケージマネージャで入れたい」となるのですが、こちらは公式リポジトリに入れるのはすごく大変ですし、野良リポジトリというのも(開発者にとっても利用者にとっても)手間がかかります。

というわけで第三の選択肢として、Snapcraftのようなクロスプラットフォームのパッケージマネージャがあります。同様のパッケージマネージャはいくつかありますが、Snapcraftは


  • Ubuntuにデフォルトで入っている

  • 公開までのフローが自動化されている

という2点から、手早く一般向けに配布する方法として良さそうな感じです。他のパッケージマネージャ(例えばHomebrewなど)はGitHubのプルリクエストベースで追加や更新を受けていることが多いですが、レビューを受けてマージされるのに1ヶ月以上かかることもあります。SnapcraftはRustにおけるcrates.ioと同じくユーザ操作だけで公開まで行くので、慣れればすぐです。

また、Snapcraftは公式にRust製ソフトウェアのパッケージ化に対応していたり、GitHubと連携できるCI環境があったりと、かなり便利に出来ています。

今回は

procs:新しいプロセス表示・検索ツール

http://github.com/dalance/procs

をSnapcraftのパッケージにしてみました。


手順


アカウント作成

https://snapcraft.io の右上にある "Developer account" から進んでアカウント作成~ログインします。

正直全部GitHubアカウントがいいのですが、そうもいかないのでubuntu oneのアカウントを作成することになります。


GitHubとの連携

ドキュメントの手順と違いますが、最初に連携してしまうのが簡単だと思います。

ログインしたら右上のアカウントメニューから "Build with GitHub" を選んで指示に従います。

進めていって、リポジトリまで選んだらこんな感じです。

repo.png

ここで "Not registered" となっている部分をクリックして、公開する時のパッケージ名を登録できます。

"Not configured" はこの後のsnapcraft.yamlをコミットすれば自動で変わります。


snapcraft.yamlの作成

Rustっぽい部分はここだけですね。GitHubリポジトリのルートにsnapcraft.yamlを置きます。


snapcraft.yaml

name: procs

version: &version v0.8.5
summary: A modern replacement for ps written in Rust
description: |
procs is a tool to display process information.
base: core18
license: MIT

confinement: strict

architectures:
- build-on: amd64
- build-on: i386
- build-on: ppc64el
- build-on: arm64
- build-on: armhf

apps:
procs:
command: procs

parts:
procs:
source: https://github.com/dalance/procs.git
source-tag: *version
plugin: rust
stage-packages:
- libc6
- libgcc1
- libstdc++6
- zlib1g


それぞれの細かい意味は飛ばします。公式ドキュメントを見てください。

Rustに関係するところだけ補足すると、base: core18は公式のRust環境では必須です。

あとはplugin: rustと指定するくらいで勝手にcargo build --releaseしてできたバイナリをパッケージしてくれます。

このファイルをコミットしてしばらく待つと以下のようにConfiguredにチェックが付いて、勝手にビルドされます。

repo2.png


リリース作業

あとは説明用のページを作ったり、ビルドに成功したパッケージをstableに指定したり、といった作業があります。

Web UI上の操作なので雰囲気で分かると思います。


インストールを試す

ここまでくればUbuntu環境から以下のようにインストールできます。

$ sudo snap install procs


(補足)ターゲットアーキテクチャについて

Snapscaftはデフォルトでは amd64/i386/ppc64el/arm64/armhf/s390xの6つのアーキテクチャ向けにビルドされます。

このうちs390xはSnapcraftのRust環境が未対応でビルドできません。

snapscaft.yamlarchitecuturesを書かないと毎回ビルドを試みて失敗することになるので、明示的に除外しましょう。

残りの5つはビルドできていいはずですが、32bit系のi386/armhfはうまくいきませんでした。

i386はリンカが見つからないエラー、armhfはrustupに失敗する、という状態です。

一応この2つはビルドできるようにしたいと思っていて現在調査中です。


(2019/6/13追記) i386ビルド

i386でビルドが失敗する問題は、SnapcraftのRustプラグインが生成する.cargo/config内のリンカ指定が間違っていたためでした。これを修正したPRを取り込んでもらったところ、i386でもビルドが成功するようになりました。