最近は組み込みの分野で CI/CD を構築していました。
組み込みの世界は物理的な状態変化が伴うので、 Web や業務アプリで使われているようなソフトウェア・エンジニアリングのプラクティスが簡単には適用しづらい所があります。そのような障害はありつつも、いくつもの製品がどんどんアップデートを繰り返す中で、テストやリリースを自動化しないとどうにもならないという機運が高まってきたので、今回仕事の中で挑戦することになりました。
今回はその取り組みが良い感じにできてきたので、時間をもらって記事にしてみました。
Before/After
従来の開発では
- デバイスベンダーの IDE
- 手動リリース
だったものが
- VS Code
- Makefile
- GCC
- Jenkins でリリース
になりました。気合と根性のリリースがいくらか解消されて良い感じです。
やったこと
- VS Code を中心とした開発スタイルの確立
- IDE のプロジェクトファイルを変換(するためのスクリプト)
- Jenkins の構築と Job の設定
VS Code を中心とした開発スタイルの確立
具体的には、サンプルアプリのプロジェクトに対して以下のことができるようにしました。
- VS Code からビルド・デバイスへの書き込み
- ログの取得・デバッガの利用
ビルドはサンプルについていたものを改造して、 Debug/Release/Test ビルドの定義を行いました。 Test ビルドは起動時に Unity Test でテストを行い、ログに結果を出力します。
ログの取得・デバッガは、ベンダーから出ている Debug Server をバックグラウンドで起動して、 GDB を起動します。 VS Code から実行する GDB サーバーの起動スクリプトは以下のような感じです。
#!/bin/bash
GDBサーバーのコマンド $@ | sed --unbuffered 's/^/[GDBサーバーログの Prefix] /' &
sleep 1
ログ表示のコマンド | sed --unbuffered 's/^/[ログの Prefix] /' &
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
wait
これを .vscode/launch.json
の debugServerPath
に設定し、通常通り VS Code のデバッグ機能が使えるようにしました。
IDE のプロジェクトファイルを変換
しばらくは並行期間を作りたいので、 IDE の設定を元に Makefile や VS Code の設定を生成するようにしました。ソース・インクルードパスやマクロの定義、コンパイラオプション、リンカの設定などが対象です。情報が充実しているとは言えませんが、 C のビルドをやったことがあるような人なら名前からおおよそ対応付けができる感じでした。
Jenkins の構築と Job の設定
本当は Groovy とかでビルドの設定をコード化できると良いのですが、今回は簡易的に以下のような設定を行いました。
#!/bin/bash
if [ -x ./scripts/jenkins.sh ]; then
./scripts/jenkins.sh
else
echo -e "\033[1;43m WARN \033[00m ./scripts/jenkins.sh is not configured." 1>&2
fi
これで scripts/jenkins.sh
さえいじれば誰もがビルドスクリプトを変更できます。完璧とは言えませんが、お手軽に Travis CI などに近い使用感が得られます。
jenkins.sh
の内容はおおよそ以下のような内容です。
- Lint
- デバイスを必要としないホストマシン上の単体テスト
- ビルド
- デバイスへの書き込み
- 実機自動テスト
- (リリース時のみ)配布用パッケージの作成・テスト環境へアップロード
※追記:実機自動テストは安定稼働が難しく結局やめてしまいました。手元の開発では引き続き利用しています。
SaaS を利用せずに Jenkins を自前で構築したのは、実機のテストを行いたかったからです。現在はそれほど複雑なテストは行っていませんが、今後はセンサーなどと組み合わせて自動化の範囲を拡大できたらと構想しています。 CI/CD の導入自体に加えて、自動化されたテストで積み上げを作って行きたい所です。
まとめ
組み込みの世界でも、 Web や業務アプリで行われているような CI/CD が実現できました。組込の CI/CD の障壁の一つは、 GUI のツールが充実していて CUI で自動化しようとすると少なからずリバースエンジニアリングが必要になってくる点があるかと思います。今回は充実してはいないものの、一応用意はされていたので、そこまで困難ではありませんでした。しかし、クローズドなツールに隠されてしまうと、このような取り組みは一気に難しくなってしまいます。また、ビルドや開発ツールチェーンのような低レイヤの知識は、なかなか身につける環境が無いという問題もあります。このあたりさえ突破すれば、開発プロセスをモダンに作り変えることができます。
今回これできたのは、 アプリ・組み込み・ハードのエンジニアがうまく連携できていることが一つ要因にあるかなと思います。ここからさらに静的解析を導入したりや自動テストを洗練させたりさせて、今よりももっと高品質な製品リリースを目指してまいります。また、このような取り組みに興味がございましたらぜひ一緒にやっていきましょう!
追記: 組込 1 年目のエンジニアが開発環境を整備した話 でその後の取り組みをより詳細に紹介しております。