Travis CI で Linux (x86_64, i686, aarch64) 向け(とついでに macOS 向け)に Rust で書いたツールのバイナリをリリースする
git-brws のリリース で微妙に Travis CI 上の rust 環境でハマったのでメモ.
前提として,cargo build
でビルドできるものとします.Travis の環境はツールチェーンが古いと困るので Ubuntu 14.04 を使ってます.今回は下記の環境向けのバイナリをビルドしてリリースしました.
Linux は musl libc を使う選択肢もありますが,使い慣れた glibc にしました.
3行で
ビルド環境
まずは matrix:
でビルドを回すジョブを書いておきます.これによって,1回の CI で4つのビルドが走ります.
matrix: include: - os: osx rust: stable env: TARGET=x86_64-apple-darwin - os: linux rust: stable env: TARGET=x86_64-unknown-linux-gnu - os: linux rust: stable env: TARGET=i686-unknown-linux-gnu - os: linux rust: stable env: TARGET=aarch64-unknown-linux-gnu
cargo
でビルドするときにターゲットを指定する必要があるので $TARGET
変数に triple を指定しておきます.未指定だとデフォルトのターゲットが使われるので実質必要なのはクロスコンパイルが必要な i686-unknown-linux-gnu だけですが,Travis のビルド一覧で分かりやすいので書いておきます.
os:
は osx
だと macOS が,linux
だと Ubuntu 14.04 が使われます.
Deploy 設定を書く
deploy: provider: releases api_key: secure: XXXXX file: git-brws-${TRAVIS_TAG}-${TARGET}.zip skip_cleanup: true on: repo: rhysd/git-brws # On specific condition -> condition: $TRAVIS_RUST_VERSION = nightly # # Only deploy tagged commit tags: true
初期設定は travis
コマンドがやってくれるので,gem install travis
して travis setup releases
するいつものやつで生成し,そのあと自分用の設定を足します.
今回はビルド後の before_deploy
で zip に固めているので,生成物を削除されないように skip_cleanup
を付けています.また,タグを打ったときだけリリースしてほしいので,tags: true
を指定してます.
ここまでが Travis の一般的なリリース設定です.
rustup を自前で入れる
Travis の rust ツールチェーンの管理は,rustup がまだシェルスクリプトで書かれていた頃のものを使っているようなので,最新の rustup
コマンドを入れます.
before_script: - sh ~/rust/lib/rustlib/uninstall.sh - export PATH="$PATH:$HOME/.cargo/bin" - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION - rustc -V - cargo -V
$TRAVIS_RUST_VERSION
でインストールされるツールチェーンのバージョンを指定しているので,新しい rustup
でも同じバージョンの Rust がインストールされます.
ここは Travis の環境が更新されればいずれ要らなくなるかもしれません.
ターゲットの追加
i686 向けのビルドにはクロスコンパイルする必要があるので,i686 向けのツールチェーンを入れます.
before_script: - if [[ "${TARGET}" == "i686-unknown-linux-gnu" ]]; then rustup target add $TARGET; fi
また,aarch64 向けの gcc はコマンド名が aarch64-linux-gnu-gcc
なので,cargo
がリンク時にそっちを使うようにします..cargo/config
に TOML 形式でビルド設定を書けます.
before_script: - | if [[ "${TARGET}" == "aarch64-unknown-linux-gnu" ]]; then rustup target add $TARGET aarch64-linux-gnu-gcc -v mkdir -p .cargo echo "[target.${TARGET}]" > .cargo/config echo "linker = \"aarch64-linux-gnu-gcc\"" >> .cargo/config cat .cargo/config fi
また,今回は glibc を使ってビルドするので,リンクに 32bit 環境の gcc を入れます.これには apt addon を使って gcc-4.8-multilib パッケージをインストールしておけば OK です.gcc-multilib は gcc 4.4 でかなり古いので gcc-4.8-multilib にしました.
addons: apt: packages: - gcc-4.8-multilib - gcc-4.8-aarch64-linux-gnu - gcc-aarch64-linux-gnu - libc6-arm64-cross - libc6-dev-arm64-cross
ビルドして zip に固める
ここは普段通りリリースビルドして成果物を入れるディレクトリをつくり,zip に固めるだけです.各環境向けに $TARGET
を指定してやります.
before_deploy: - cargo build --target $TARGET --release - mkdir "git-brws-${TRAVIS_TAG}-${TARGET}" - cp target/$TARGET/release/git-brws LICENSE.txt README.md "git-brws-${TRAVIS_TAG}-${TARGET}" - zip "git-brws-${TRAVIS_TAG}-${TARGET}.zip" -r "git-brws-${TRAVIS_TAG}-${TARGET}"
これで tag 付きのコミットが push されるとクロスビルドに必要なツールが入り,ビルドされ,成果物が zip で GitHub のリリースページにアップロードされるはずです.
また,上記の設定で macOS でもビルド及びリリースできているはずです.
今手元に Windows マシンが無いのでできませんが,AppVeyor でのビルドも try してみる予定です.