2015 年やったこと - Mozc 編

1 年遅れぐらいになりますが,OSS Mozc 関係で 2015 年にやったことのまとめです.

空き時間を利用したプロダクトチーム外からのコミットということで,新規機能に関しては引き続き何も行っていません.前年と同じく OSS プロジェクトとしての環境整備と技術的負債の解消に注力した年でした.

以下が主な活動内容です.

  • Google Code (Subversion) から GitHub (git) への移行を完了
    • 過去のコミット履歴を可能な限り維持
    • ドキュメントを Markdown で書き直す
    • Travis CI および AppVeyor を利用し,サポートしている全プラットフォームについて CI (Continuous Integration) を実現
      • Android
      • Linux desktop
      • NaCl
      • Windows
      • macOS
  • コードの簡略化
    • プロダクションに使われなかった実験的コードの削除
    • サポートを終了した古い OS 向けコードの削除
    • 積極的にコンパイラをアップグレードし,C++ 11 のライブラリでコードを書き換え
      • Windows 環境は Visual C++ 2010 から 2013 を経て 2015 へ
      • 非 Windows 環境は GCC から Clang / libc++ に移行
      • base/hash_tables.hstd::unordered_map / std::unordered_set に置き換え
      • mozc::scoped_ptr<T>std::unique_ptr<T> に置き換え
  • Windows 10 向けの緊急性の高い問題の修正

コミット単位でみる作業まとめ

Windows XP 向けコードの削除

以前は最低サポート環境が Windows XP であったため,Windows Vista 以降に追加された API は GetProcAddress で動的にリンクするというスタイルで統一されていました.Windows XP 廃止後も同様のコードは動くことは動くのですが,コードが不必要に長くなるだけでなく,Loader Lock に代表されるような同期的モジュール解決の問題すらも不必要に呼び込んでしまいます.そこで,Windows Vista 以降に追加された API に関しても可能な限り暗黙的なリンク (Implicit Linking) に変更したのが主な変更内容です.

少し冒険してみた点としては,DLL の Import Library が提供されない input.dll についても,ビルドルールを工夫して暗黙的にリンクするようにしてみたということでしょうか.基本的には DLL から「正しい」LIB ファイルを作るには と同じことを行っています.

Android 版の不要なコードの削除

サポートバージョンを上げたことにより不要になったコードを削除しました.

Visual C++ 2013 への移行

Mozc の Windows 向けビルドは,2015 年始めの時点では依然として Visual C++ 2010 を使用しており,これが C++ 11 移行の大きな障害となっていました.これをまずは Visual C++ 2013 段階までアップグレードするという試みです.これに付随して,Windows Kit (Windows SDK) 8.1 に追加されたライブラリや定数を使ったコードの簡略化も行いました.

この過程で遂に実現できたもののひとつに,NOMINMAX マクロをプロジェクト全体に適用することに成功した,というものがあります.そうです,<windows.h> を include するだけで,min/max というプリプロセッサマクロが定義されてしまうという問題が,commit 2cc1a055 によってついに過去のものとなったのでした.

Visual C++ 2015 への移行準備

2015 年の年末にかけて,さらに Visual C++ 2013 から Visual C++ 2015 への移行の下準備を行いました.移行の完成は 2016 年を待つことになりますが,2015 年の段階である程度の下準備 (Google TestProtocol Buffers のアップデート等) を完了することができました.

C++ 11 対応

Visual C++ 2013 への移行でいよいよ C++ 11 対応の目途がたったことから,まずは全プラットフォームで C++ 11 が前提とできるようにビルドルールの変更等と行いました.この過程で STLPort を利用した Android ビルドを非サポートとしたり,非 Windows 環境のデフォルトコンパイラを Clang に統一したりといった変更も行っており,全体としてはビルドルールの簡略化に貢献できたものを考えています.

その後,実際に C++ 11 の新しいライブラリを用いて以下のような置き換えを行いました.技術的に難しいところはないものの,単純に多数のファイルを変更する必要があるため,時間に余裕があるときでないとなかなか難しい作業です.

  • base/hash_tables.hstd::unordered_map / std::unordered_set に置き換え
  • mozc::scoped_ptr<T>std::unique_ptr<T> に置き換え

実験的コードの削除

Remove unused code from mozc_tool · google/mozc@51b1f78 · GitHub

もしかしたら将来使うかも,と導入したものの,結局プロダクションで使われなかったコードの削除も行いました.例えば上記コミットで削除されているコードは,1,000 行以上もありながら Windows 専用かつプロダクションでは一度も使われていないという正真正銘デッドコードです.

ibus-mozc 廃止に向けた下準備

予定されていた ibus-mozc廃止は結局 2015 年中に行われませんでしたが,そのための下準備としていくつか ibus-mozc 関連のコードのクリーンアップを行っています.

一番入れたかった変更は commit 7a129e65 で,mozc_server 中にある ibus-mozc 専用コードを今のうちに削除しておくというものです.このコードは,IMR_QUERYCHARPOSITION NSTextInputClient firstRect と同様の機能をなんとか Gtk+ IM Module 上に実現しようとしたものの名残で,クライアントコードはなるべく簡潔にするという Mozc の設計思想に基づき mozc_server 側にエミュレーションコードが実装されました.しかしながら,Mozc Issue #243 で議論されているように本質的に解決できないコーナーケースが存在すること,および ibus-mozc 以外では使用されていないこと,という 2 点の理由から,ibus-mozc 廃止前に完全に削除しておきたかったのでした.

GitHub への移行と Continuous Integration (CI) の整備

Google Code のサービスを終了にともない,OSS Mozc についても GitHub への移行を行うこととなりました.当時は私自身あまり git に慣れていなかったこともあり,Subversion から git への移行をあれこれ試行錯誤するのにずいぶんと時間を使ったように思います.

とはいえ移行が済んだあとは GitHub のエコシステムに感心するばかりでした.特に CI については最終的にサポートしている全プラットフォームについて自動ビルドをセットアップすることができ,マルチプラットフォーム対応に価値を置いているプロジェクトとしては本当に助かっています.

Travis CI のセットアップ

AppVeyor のセットアップ

gclient から git submodule への移行

Windows 10 対応

Windows 10 で状況が変わった点についてもいくつか緊急的な修正を行いました.

  • 言語バーが Store App でも使われるようになったことへの対処
  • サンドボックス下で実行されるアプリケーションから mozc_server プロセスを起動できないという制約が Windows 8.1 時代よりも目立つようになったため,いくつかの対症療法的な変更

不安定なテストの改善

Travis CI 上で不安定だったテストについて安定化を試みました.

透明度付き PNG ファイルを PBGRA32 形式の Bitmap ファイルの変換するツールを作成

ちょうど 2015 年,会社のロゴが更新され,候補ウィンドウに表示される画像も変更する必要ができました.

Windows 版の mozc_renderer は,会社ロゴの表示に GDI の AlphaBlend API を利用しています.問題はこの API はいわゆる乗算済みアルファ フォーマット (正確には PBGRA32 形式) を期待していることです.デザイナーさんから渡された PNG ファイルを PBGRA32 に変更する必要があったですが,適当なツールがみつからなかったので急遽作ったのがこちらのコードでした.

雑感

以前から興味のあった GitHub 上での作業や CI について一通り体験することができたのは非常に有意義でした.また,git filter-branchgit rebase を使ったコミット履歴の編集を学ぶ上でも良い機会でした.

一方,前年に引き続きメンテナンス作業に注力して実感したのは,ソフトウェアのメンテナンスというのは本当にコストがかかるというというものでした.OSS Mozc に関して言うと,以下の作業だけで年間 100 時間は軽くかかっています.

  • コンパイラのバージョンを上げる
  • 依存するライブラリのバージョンを上げる
  • 丁寧にリリースノートを書く
  • ドキュメントを最新の状態に維持する
  • Issure Tracker に報告された問題に丁寧に答える

自分の場合これらの作業に有給休暇 10 日分以上を消費していることになるわけで,今後も同程度の貢献が継続可能かというと大変に疑問です.各種 Linux ディストリビューションで OSS Mozc が採用されるのはありがたい一方,最大の不安は期待値が高くなりすぎることです.将来のメンテナンスも含めて,あくまで無保証で提供されているという点を今一度思い出していただければという次第.

過去の関連エントリ