Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

RustのCI環境でクロスコンパイルを行う

こんにちは
@maron8676です

今回は、RustプロジェクトでのCI環境構築について紹介します。
最近、自然言語処理のエンジン開発をRustで行っており、その中で実際に試した内容となっています。

Rust

Rustは安全性を担保しつつ、高速なアプリケーションを開発するのに便利なプログラミング言語です。
例えば、以下のような特徴があります。

  1. 同じ値の種類でも、不変な変数と可変な変数では別の型になっており、意図しない変更をコンパイルエラーとして検知できる
  2. ポインタの有効範囲がプログラムで示されるため、無効なアドレスへの参照をコンパイルエラーとして検知できる

公式ページには、以下のように書かれています。

RustはMozillaとコミュニティによって作成された、オープンソースプログラミング言語です。
開発者が最新のマルチコアプロセッサの強力な機能を最大限に活用して、高速で安全なアプリケーションを作成できるように設計されたおり、セグメンテーション違反を防ぎ、スレッドの安全性を保証します。

バイナリの自動作成

Rustで書かれたプログラムを実行するには、実行環境に合わせてコンパイルを行い、実行可能バイナリを作成する必要があります。
Rustのコンパイルは他言語と比較して遅めなので、pushなどをトリガーにしてコンパイルを行います。
実行可能バイナリを作成できるとすぐにバイナリを利用できて便利です。
ここでは、GitLab CI/CDを使ってWindows用バイナリを自動作成する方法を紹介します。

通常のビルド、実行手順

CI環境のビルド方法を見る前に、通常ローカルPCで行うビルド、実行手順について見ていきましょう。
Rustには、cargoというコマンドが含まれています。
このコマンドでビルド、パッケージ管理、ドキュメント生成といった、開発に必要な作業を簡単に行うことができます。

では、ビルド手順を見ていきます。コマンドプロンプトでプロジェクトディレクトリまで移動して、

cargo build

を実行することで、プロジェクトをビルドできます。
--release オプションを付けると、プロダクションビルドできます。
ビルドが成功した場合は、

cargo run

でプログラムを実行できます。
ビルドが成功した時点で、プロジェクトディレクトリのtarget配下にexeファイルが作成されています。
そのため、その場所まで移動したり、ファイルを移動したりして、直接実行も可能です。

CI環境でのビルド手順(GitLab CI/CD パイプライン設定)

全体としては以下のようになります。
こちらを実行することで、GitLabCIのPipelinesからビルド結果のファイルをダウンロードできるようになります。
f:id:acro-engineer:20200509104404j:plain

image: ubuntu:18.04  # 1. image選択

variables:
  TOOLCHAIN: "1.41.1"
  TARGET: "x86_64-pc-windows-gnu"

build:
  script:
    - apt update && apt install -y --no-install-recommends ca-certificates curl gcc g++ g++-mingw-w64-x86-64 # 2. 必要なパッケージのインストール
    - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $TOOLCHAIN -t $TARGET # 3. Rustのインストール
    - export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc-posix CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++-posix # 4. 環境変数の設定
    - cargo build --target $TARGET # 5. ビルド
  artifacts:
    paths:
      - target/x86_64-pc-windows-gnu/release/my_project.exe # 6. 成果物の保存

各要素の説明

  1. image選択
    実はRust公式のdockerイメージ(debianベース)があるのですが、
    debianベースで試行錯誤してもwindowsコンパイルを成功させることができなかったため、
    cross*1を参考にして、ubuntuベースで作ることにしました。
     
  2. 必要なパッケージのインストール
    scriptの1行目では、Rustのインストールに必要なca-certificatesとcurl 、ビルド時に必要なgcc関連をインストールしています。
     
  3. Rustのインストール
    scriptの2行目では、Rustをインストールしています。
    インストール時に--default-toolchainオプションでRustバージョンを、
    -tオプションでビルドターゲットに加える内容を指定できます。
     
  4. 環境変数の設定
    scriptの3行目では、ビルド設定に関わる環境変数を設定しています。
     
  5. ビルド
    scriptの4行目でビルドを行っています。
    cargo buildコマンドに--targetオプションを付けることで、ビルドターゲットを指定できます。
    今回はWindows64bitをターゲットにしています。
     
  6. 成果物の保存
    ビルド結果は所定の場所にできるため、成果物として登録しています。
    ファイル名がmy_project.exeとなっていますが、これはCargo.tomlのnameに書かれた文字列が使われます。

まとめ

本記事では、RustプロジェクトをクロスコンパイルするCI設定について紹介しました。
ビルドの遅さをカバーして、実行時だけでなく開発や動作確認のスピードも上げていきたいですね。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWebエンジニアの求人 - Wantedlywww.wantedly.com

*1:crossは実行環境でdockerが使えることを前提としているので、
CIジョブのランナーとしてdockerコンテナを使用する場合は、docker in dockerとなってしまいビルドできません。