株式会社クリアコード > ククログ

ククログ


OSSへのフィードバックをしてみたいけど、何をフィードバックしたらいいのか分からない

結城です。

これまで、「OSSを使用していてトラブルに遭遇しているか、改善の提案があり、その情報を開発元のイシュートラッカーに伝えようとしている」という人向けの情報として、「どういう場所に報告するのが適切か」「どんな内容を書くのが適切か」という話をしてきました。

しかしOSS Gateワークショップにビギナーとして参加された方の中には、そういった「どうやるか」の前の段階の話として、「フィードバックしたい情報」をまだ持っていないという人もいます。というか、「別に今の段階で何か具体的にOSSの使用上で困っているわけではないが、とにかくOSS開発に関わりたい、OSS開発に関われる人になりたい」という人の方がまだ数としては多く、OSS Gateワークショップはまさにそのような人を想定した内容になっています。

なので、OSS Gateワークショップでは「フィードバックするネタ*1の見つけ方」からやるようにしています。この記事ではワークショップで実際に伝えているやり方も含めて、「フィードバックするネタ」の見つけ方を紹介します。

どのOSSにフィードバックするか

ネタを探すには、当然ですが、ネタを探す先のOSSが必要です。

ワークショップに来られた方に「このOSSにフィードバックしたいなあ、というプロジェクトは何かありますか?」と聞くと、「Linuxカーネル」や「Docker」といった有名なプロジェクトの名前を挙げられる事が結構あります。

ワークショップでは「なるべく普段から使っているOSSを題材にしましょう」と案内しているので、その意味ではこれらの名前を挙げても間違いではないのですが、単に「OSS」と言われてそれらの有名なプロジェクトくらいしか思い浮かばなかったと見受けられるケースでは、筆者はなるべく、もっと身近な・小規模のプロジェクトをお薦めするようにしています。というのも、有名だったり大規模だったり歴史が長かったりするOSSは、「別に今の段階で何か具体的に使用上で困っているわけではない」という人がフィードバック先にするには色々とハードルが高い事が多いから*2です。

「普段使っているOSS」を意識してみよう

「身近なOSS」なんて思いつかない、という人でも、普段の仕事で使うアプリケーションやコマンドを作業の順番に従って思い浮かべてみると恐らくOSSがいくつも見つかるはずです。例えば以下の要領です。

  • インターネット上の情報を調べるためにChromeを起動した。
    • ChromeのベースとなっているChromiumはOSSです。
    • Chrome/Chromiumが依存しているcrc32cdom-distiller-jsenum34などの多数のライブラリ( chrome://credits/ で確認できます)もOSSです。
    • Chrome/Chromiumで使える拡張機能にもOSSが多くあります。
  • 作業を始めるために、ターミナルを起動して、Bashの上でgit cloneを実行した。
    • GitはOSSです。
    • BashもOSSです。
  • Ruby on Railsで構築されたサービスのユニットテストを走らせるために、bundle instalLしてrake testした。
    • Ruby on RailsはOSSです。
    • RubyもOSSです。
    • RailsやRailsアプリケーションのGemfileに従ってbundle installでインストールされた多くのGemもOSSです。
    • bundleコマンドを提供するBundlerもOSSです。
    • rakeコマンドを提供するRakeもOSSです。
  • ソースコードを編集するためにVisual Studio Codeを起動した。
    • VSCodeはOSSです。
    • VSCodeのベースになっているElectronもOSSです。
    • ElectronのベースになっているChromiumもOSSです。
    • VSCodeで使えるプラグインにもOSSが多くあります。
  • Vue.jsで構築されたフロントエンドにファイルを追加し、ESLintでエラーがない事を確かめて、Babelでトランスパイルした。
    • Vue.jsはOSSです。
    • ESLintもOSSです。
    • BabelもOSSです。
    • ESLintやBabelのpackage.jsonに従ってインストールされた多くのNPMモジュールもOSSです。
  • 編集したソースコードをコミットする時、コミットメッセージの編集にVimを使った。
    • VimもOSSです。
    • VimのプラグインにもOSSが多くあります。

こうして見てみると、開発に使用しているフレームワーク自体ツールがOSSであったり、また、有名なOSSも名前を聞いた事のないような無数のOSSを利用して作られていたり、という状況である事が分かります。現代のソフトウェア開発の現場では、OSSを全く使わずにいるということはあまりないでしょう。

「OSS」の見つけ方

ところで、いきなりたくさんOSSの例を挙げましたが、そもそも「どうだったらOSSなのか?」を説明していませんでした。

OSS(Open Source Software)とは、OSIがOSSライセンスと認めているライセンス一覧に載っているいずれかのライセンスの元で頒布されているソフトウェアのことです*3。例えばVSCodeでは、「Help」→「View License」で開かれるページの冒頭に「Source Code for Visual Studio Code is available at https://github.com/Microsoft/vscode under the MIT license agreement at https://github.com/Microsoft/vscode/blob/master/LICENSE.txt.(VSCodeのソースコードはMITライセンスの元で入手可能です)」と書かれています。MITライセンスは上記の一覧にあるOSSライセンスなので、VSCodeはOSSであると言える訳です。

他にも、ソフトウェアのライセンスを調べる方法はいくつかあります*4

  • GUIアプリであれば「(ソフトウェア名)について」「ライセンス」のようなメニューからこのような情報を確認できる事があります。
  • 配布ページやプロジェクトのトップページにライセンスが書かれている事もあります。
  • 公開されているソースコードのリポジトリ上にCOPYING(著作権情報)やLICENSE(ライセンス情報)といった名前のファイルがあり、そこに詳細が書かれている場合もあります。
  • READMEに端的に「このソフトウェアは何々ライセンスです」と書かれている事もあります。

「OSSに何かフィードバックしてみたいが、具体的にはビッグネーム以外すぐに思いつけない」という場合には、まずはこのようにして、自分が直接的・間接的に使用しているOSSを掘り下げてみて下さい。LinuxカーネルやDockerよりは、ずっと身近な所にOSSを見つけられるはずです。

些細な「つまずき」に敏感になろう

題材にするOSSを決めたら、次はそのOSSを普通に使います。そうして 普通に使っている途中で遭遇した些細な「つまずき」 が、フィードバックする内容となります。

しかし、そう言われても、何が「つまずき」なのかピンと来ないという人も多いでしょう。「普段から自分もOSSを使っていた事は分かったけど、べつにつまずいた事なんて無いんだけどな……」そう思うなら、それはあなたの運がよかったか、あなたより前につまずいた他の人が道を整備してくれていたか、あるいは、あなたが「自分がつまずいたという事」自体に気付いていないかのいずれかです。

最後の「気付いていない」というのは実はよくあります。ITに詳しくない人から「エラーって言われるんだけど!」と泣き付かれて、「何かした?」と聞いても「何もしてないって!」と本人は言うばかり、というのはよく聞かれる話ですが、それと同じ事を自分でも知らず知らずのうちにしている可能性があるのです。

「そんなバカな!」と思いますか? では、以下の事に身に覚えはないでしょうか?

  • 公式に情報が無いので、「(機能の名前) 使い方」でWeb検索してQiitaやStack Overflowや個人のブログの解説を探した。
  • 動かしてみたらいきなりエラーメッセージが出た。
  • よく分からないけどWebを検索したら対処法が出てきたので、書いてある通りにやったらエラーが出なくなった。

どうでしょう。「いつもの事だから、特別つまずいたとは思っていなかった」「そんな事でいちいち立ち止まってたら仕事にならないし」と思う人もいるのではないでしょうか。ですが、これらはすべて立派な「つまずき」なのです。

つまずくのは自分のレベルが低いからではなく、説明が足りないから
  • インストール説明の手順の中に、必要な前提条件が書かれていなかったので、インストールに失敗した。ググったら、◯◯というパッケージを先に入れておかないといけないと書いてあるブログが見つかった。
  • コマンドを実行しようとしたら、初期設定をして下さいというメッセージが出てエラーになった。
  • 機能を実行しても、ちゃんと動いたかどうかよく分からなかった。

実は、これらは実際にOSS Gateワークショップでもよく登場するつまずきです。こういうつまずきに遭遇した時、「つまずいたのは自分の勉強が足りなかったからだ」「こんな所でつまずくのは初心者だけに違いない、こんな所でつまずいたと人に知られるのは恥ずかしい」と思う人は少なくないでしょう。

しかし、謙虚に学ぶ姿勢は確かに大事なのですが、ここは一旦謙虚さを忘れて、自分の気持ちに素直になってみませんか?

  • インストール説明の手順の中に前提条件が書かれていなかったのでつまずいた。→必要なパッケージがあるなら、最初からそれも手順に書いておいたり、自動的にインストールするようになってくれていたりすればいいのに……
  • コマンドを実行しようとしたら、初期設定をして下さいと言われてエラーになった。→初期設定が必須なら、インストール手順の中に書いてあればいいのに……
  • 機能を実行しても、ちゃんと動いたかどうかよく分からなかった。→確認方法も書いてあればいいのに……

ほら、改善できそうな点が見えてきましたね。

多くの小規模なOSSプロジェクトでは、インストール手順や使い方の説明などのドキュメントの整備には手が回らなくなりがちです。この手の情報は、1回使い方を習得した後は2回3回と同じ人が見返す訳ではないため、今現在関わっている人にとっては「かかる手間のわりには自分自身が恩恵を受けられない」という性質があるからです。

しかしそのような状況が長く続きすぎると、「既にわかっている人」以外にとってそのOSSはどんどん使いにくく・関わりにくくなってしまいます。そうすると、新規のユーザーや開発に関わる人が増えない一方で、関わっていた人達はライフステージの変化などにより離れていき、最終的には新機能の追加も無ければ脆弱性の修正も無い、誰にもメンテナンスされない見捨てられたプロジェクトになってしまいます。そうなって一番困るのは、一般のユーザーです。「不親切な案内を丁寧な内容に直す・補完する」のは、プロジェクト自体の長期的な継続のために重要なフィードバックと言えます。

ですので、「つまずいたのは自分の勉強不足のせい」「こんな所でつまずいたと人に知られたら恥ずかしい」という考え方は一旦封印しましょう。むしろ、 「つまずいた自分じゃなく、こんな最初の方につまずくような部分が残ってる事の方が悪い」 くらいに考えておいてちょうどいいくらいです。

「注意しなくても使える」のが一番いい

また、「使う上で注意が必要」という箇所も、フィードバックのきっかけにしやすい部分です。

例えば、筆者はFirefoxの法人利用においてポリシー設定でのカスタマイズをよく行っていますが、この機能自体は導入されてまだ歴史が浅いために、色々とこなれていない部分があります。つい最近も、「検索候補を表示するかどうか」を制御するポリシー設定がロケーションバーに対してしか作用せず、単独のWeb検索バーでは設定に関わらず常に検索候補が表示される、という制限事項に遭遇しました。

そういう制限事項を見つけた時に、「この機能にはこういう制限事項があるので、使う時は注意が必要だ」というノウハウを社内で共有したりブログやQiitaに書いたりするのは、もちろん有用な事です。ただ、そういった情報ばかりが増えていくと、新しく使い始めようとした人には「なんだか、使うのに色々勉強が必要なんだな……」「気軽には使えないんだな……」という印象を持たれ、いずれは「敷居が高そうだから、触るのやめておいた方がいいかな……」と思われるまでにもなってしまいかねません。

OSSに関わりたいと考えている人は、ぜひそこから一歩先に考えを進めてみて下さい。「使う時に特別な注意が必要ないのが一番いい」、これはどんな場合にも言える事です。 その視点で考えれば、「検索候補を無効化する設定はロケーションバーだけでなく当然Web検索バーにも反映されるべきで、そうなっていないのは不具合だ」という見方ができるようになり、「注意点」に見えていた物は「フィードバックした方がよい点」として浮かび上がってきます

実際に、先のポリシー設定の制限事項は筆者が不具合として報告した結果、改善されるべき点と認識してもらう事ができました。そして、提出したパッチが取り込まれた結果、「ポリシー設定で検索候補を表示しないように設定したら、ロケーションバーでも単独のWeb検索バーでも検索候補が表示されなくなる」という、使う上で特別な注意が必要ない状態になりました。

ドキュメントの例にしても機能の例にしても、つまずきに対して「無いならしょうがない」「駄目ならしょうがない」「変えられないんだからしょうがない」と考えていると、どうにかして自分のフィールドの中だけで物事を解決しようという、いわゆる「運用で回避」の方向に行ってしまいがちです。しかし考え方を少し変えれば、そういった「面倒事」は「解決した方がよい問題」と言い換えられます。「OSSにフィードバックするって、何か特別な事だ」「そんな事ができるのは別の世界の人だ」と思っていた人でも、そう考えてみれば、OSSへのフィードバックとは決して特別な事ではなく、日常の延長線上にある物だ、という事を実感できるのではないでしょうか。

まとめ

現代は「問題は自分で解決できる」という実感を得にくい時代かも知れません。ITの分野だけ見ても、今はスマートフォンのように分解修理が不可能な機械は多いですし、Webサービスにしても、クラウドで提供されている物に何かトラブルがあってもユーザーはただベンダーによる復旧を待つ事しかできません。「駄目なら、しょうがない」と早々に諦めなくてはならない場面は非常に多いです。

また、「未解決の問題の解決に取り組む」という事は、まさしく挑戦です。成功が確約された挑戦というものは無く、挑戦するからには失敗のリスクも伴います。「これ以上の失敗はしたくない、失敗は許されない」という空気が強いと、そういう点でも挑戦するのは憚られるものでしょう。前述したFirefoxのポリシー設定の改善提案も、Firefox開発チームの理解や協力を得ることに失敗していたら、制限がそのまま残り続けることになっていたかもしれません。

しかし、「できることは何も無い」「絶対に解決できると分かっている問題以外、取り組みたくない」と最初から諦めていると、それ以上知識も深まらなければ経験も増えません。問題に遭遇した時、「もしかしたら何か解決策があるかもしれない」「解決できるかどうか分からないけど、もし解決できるなら解決したい」と考えて試しに掘り進めてみる、それこそが多くのOSS開発者が日常的にやっている事です。「OSS開発者という人になりたい」という思いは一旦脇に置いて、まずは「OSS開発者がしているような考え方をして、OSS開発者がしているような行動を取る」という事を実践してみて下さい。そうして行動している人、それが「OSS開発者」の正体です。

「OSS開発者」は、プロのスポーツ選手や士業のように試験に合格すればなれる物でも、名誉として手に入れる肩書きでもありません。行動しているという状態こそが「OSS開発者」なのだと言えます。行動すればすぐになれる「OSS開発者」に、皆さんも是非なってみて下さい。

そのような行動をいきなり一人で始められる自信が無いという方は、OSS Gateワークショップがいいきっかけになるかもしれません。東京以外の地域でもワークショップが開催されていますので、一度足を運んでみてはいかがでしょうか。

*1 OSS Gateワークショップでは「フィードバックポイント」と呼んでいます。

*2 例えば、Issue Trackerではなくメーリングリストが主な情報のやり取りの場だったり、独自の高機能なイシュートラッカーを使用していたり、プルリクエスト形式ではなく伝統的なパッチの形で修正を送る必要があったりという事があります。

*3 他の意味・定義でOSSという言葉を使う人もいますが、OSSという言葉を生み出し広めたOSIはそのように定義しています。

*4 多くのOSSライセンスは「何らかの形でライセンス名を明記する事」を利用条件に含めているため、根気よく調べると何かしらの情報を見つけられるようになっているはずです。OSSではない物をOSSと誤認して二次利用すると、もしかしたら訴訟を起こされたり賠償を求められたりするかもしれませんので、ライセンスに関する情報を見つけられない場合は安全側に倒して、OSSではない物と判断する事をお勧めします。

2019-07-08

Firefoxのトラブルシューティング:Firefox 67以降のバージョンを起動すると意図せず別プロファイルが作られてしまう

2019年8月29日追記:この問題はFirefox 69以降およびFirefox ESR68.1.0以降では修正済みです。本稿はFirefox 67~68.0.x(ESR含む)に特有の現象についての解説となります。

Firefox 67以降のバージョンではFirefoxのインストール先ごとにプロファイルが作られるようになったという事をご紹介しました。しかし、起動の仕方によっては意図せず新しいプロファイルが作られてしまうという場面があります。

例えば、

  • デスクトップ上のショートカットからFirefoxを起動した時
  • コマンドプロンプト(cmd.exe)からパスを明示してFirefoxを起動した時
  • メールクライアントの本文内のURLをクリックして、URLを開く既定のアプリケーションとしてFirefoxを起動した時
  • テキストエディタから登録済みの外部アプリケーションとしてFirefoxを起動した時
  • Google Chrome用拡張機能を使ってリンク先をFirefoxで開いた時

のような場面で、同じ位置にインストールされているFirefoxなのに、それぞれ別々のプロファイルが作られてしまうという事が起こり得ます。これは何故でしょうか、そしてどうすれば回避できるでしょうか。

原因

この問題は、プロファイルを紐付ける対象のパスが正規化されず、大文字小文字が厳密に区別される事が原因で発生します。

通常、Windowsではファイルパスの大文字小文字は区別されません*1。また、ファイルには古いアプリケーション向けに、MS-DOS互換の短い名前が付いている場合があります。これらの理由から、一般的にWindows上では以下のパス表記はすべて等価に扱われます。

  • C:\Program Files\Mozilla Firefox(正式)
  • c:\Program Files\Mozilla Firefox(ドライブレターのみ小文字)
  • c:\program files\mozilla firefox(すべて小文字)
  • C:\PROGRAM FILES\MOZILLA FIREFOX(すべて大文字)
  • C:\PROGRA~1\MOZILL~1(MS-DOS互換の8.3形式)

ところが、Firefoxがインストール先パスとプロファイルとを紐付けるために使う情報は、当該フォルダのNTFSでのオブジェクトIDでもなければ正規化されたパス文字列でもなく、これらを単純な文字列として計算したCity Hash値です。City Hash値*2はパスの表記の仕方ごとに

  • C:\Program Files\Mozilla Firefox308046B0AF4A39CB
  • c:\Program Files\Mozilla Firefox4FD4C3CBEC5FE500
  • c:\program files\mozilla firefox4D589497A5E2C2E9
  • C:\PROGRAM FILES\MOZILLA FIREFOXB86E4C730D96F15B
  • C:\PROGRA~1\MOZILL~1A86124024953D658

と変化し、FirefoxはこのCity Hash値に対してプロファイルを作成し紐付けるため、「起動する時のパスの指定の仕方によってプロファイルが変わってしまう」という事が起こる訳です。

Firefoxを起動する手段が関連付けのみに依っているのであれば、この問題には遭遇しにくいです。問題が起こりやすいのは、ユーザーが明示的に文字列としてパスを指定する場合です。上記の例の「テキストエディタの登録済みの外部アプリケーション」や「Google Chrome用拡張機能で起動する外部アプリケーション」としてFirefoxを指定する場面では、正式な表記とは大文字小文字が異なるパスを自分で入力してしまいがちだからです。

対処

この問題はBug 1555319 - The case insensitive file system on Windows makes it possible to run Firefox with seemingly different installation pathsとして既にトラックされており、Firefox 69では修正済みとなっています*3。ただ、Firefox 68向けには修正がバックポートされていない*4ため、Firefox 67から68までのバージョンを使っている場合は手動での対策が必要です。

原因は上記の通りなので、対処としては、Firefoxを起動するためにパスを指定している箇所すべてについて、パス表記を正式な表記に揃えるという事になります。

正式なパス表記は、ファイルのプロパティを開いて「全般」タブの「場所」欄に表示される物です。firefox.exeをデスクトップなどにドラッグしてショートカットを作成し、そのプロパティを開いて「リンク先」欄の内容を参照しても同じパスを得られます。これらの方法で正式なパス表記を調べたら、Firefoxのパスを指定していた箇所を探して地道に設定し直していきましょう。

まとめ

Firefox 67以降のバージョンについて、起動の方法によって違うプロファイルが使われてしまう場合があるという問題の原因と回避策を解説しました。

当社ではFirefoxの法人での使用上で起こる様々な問題について、原因や回避方法の調査を有償にて承っています。社内でのFirefoxの運用でお困りのシステム運用担当者の方がいらっしゃいましたら、ぜひメールフォームよりお問い合わせ下さい。

*1 NTFSであればfsutilコマンドを使って特別な属性を与えることでファイル名の大文字小文字を区別するようにする事もできますが、伝統的なWindowsアプリケーションはファイルパスの大文字小文字が区別されない前提で設計されているため、一般的にはこの機能は使われていません。

*2 ファイル名部分を除外した、フォルダのパスのハッシュ値が使われます。

*3 Firefox側でパスを正規化してからCity Hash値を求めるようになりました。

*4 Firefox 69のブロッカーバグとして修正されたものの、Firefox 68に修正をバックポートするには遅すぎたとの事です。Firefox ESR68については、Firefox ESR68.1.0の時点で修正がバックポートされる見込みです。

タグ: Mozilla
2019-07-05

MariaDBへ不具合をフィードバックするには

はじめに

MySQL/MariaDB用のストレージエンジンのひとつにMroongaがあり、MySQL/MariaDBユーザーに高速な日本語全文検索機能を提供しています。
先日リリースされたMroonga 9.04では、MySQL 8.0向けのパッケージの提供(CentOS 6とCentOS 7)もはじまりました。

クリアコードでは、Mroonga関連プロダクトのサポートサービスを提供しています。
今回は、サポートサービスをきっかけにMariaDBへ不具合を報告し、修正されたケースがあったのでその事例を紹介します。

不具合の発覚のきっかけ

Mroongaでは、ユーザーの利便性のためにMariaDBにMroongaをバンドルしたWindows版のパッケージを配布しています。
不具合発覚のきっかけは、Windowsでこのパッケージを利用中のお客様からの「レプリケーション中にスレーブがとまる」という報告でした。

実際にお客様から提供された問題発生時のログを確認すると、次のようなメッセージが記録されていました。

[ERROR] Semisync slave socket fd is 580. select() cannot handle if the socket fd is greater than 64 (FD_SETSIZE).
[Note] Stopping ack receiver thread

このエラーメッセージに対応するのはMariaDBの以下の実装箇所でした。

該当するソースコードを抜粋すると次のようになっていました。

#ifndef WINDOWS
      if (socket_id > FD_SETSIZE)
      {
        sql_print_error("Semisync slave socket fd is %u. "
                        "select() cannot handle if the socket fd is "
                        "greater than %u (FD_SETSIZE).", socket_id, FD_SETSIZE);
        return 0;
      }
#endif //WINDOWS

ソケットのファイルディスクリプターの値が大きいせいで、スレーブからのackを受け取るスレッドが止まっていました。
「Windows以外で」上記のチェックが有効なはずなのに、実際には「Windowsで」エラーが発生していました。
これは、#ifndef WINDOWSWINDOWS が定義されていないことによるものでした。
通常こういう場合は #ifndef _WIN32 が使われるので、正しくありません。

実際、他の実装としてMySQLを確認したところ、Bug#23581389 として一年半以上前にまったく同じ問題の修正がなされていました。

不具合を報告するには

MariaDBの場合、MariaDB bugs databaseに不具合を報告します。

遭遇した問題は既知の問題として報告されていなかったので、新規課題の「作成」をクリックして問題を報告しました。
(課題の報告にはあらかじめアカウントを作成してログインが必要です。)

対象コンポーネントは「Replication」を選択し、環境には「Windows」であることを明記しました。
問題の説明では、エラー発生時のログや、実装のどこが問題であるかに言及しました。

実際に報告した内容は次のとおりです。

MDEV-19643の不具合報告

この問題については、報告から1ヶ月しないうちに修正されました。
修正版はMariaDB 10.3.17や10.4.7としてリリースされる見込みです。

まとめ

今回、サポートサービスをきっかけにMariaDBへ不具合を報告し、問題が修正されたケースがあったのでその事例を紹介しました。
Mroongaに限らず関連プロダクトのサポートが必要な方は問い合わせフォームからご相談ください。

2019-07-01

GNU/Linux版Firefoxでime-modeを動作させるアドオン

ime-modeとは

CSSにはime-modeというプロパティがあり、これによりinput要素やtext要素でインプットメソッドの入力モードを制御することができます。この仕様は廃止されることが決まっているため積極的に利用すべきものではありませんが、一方で代替となる仕様や実装が無いこともまた事実です。日本の業務システムでは、入力業務効率化の必要性から、今なおこの機能を利用している事例も多いようです。

Firefoxでのime-modeサポート状況

この仕様はInternet Explorer由来のものですが、Firefoxも同仕様をサポートしています。ただし、GNU/Linux版ではサポートされている機能が限定的で、activeinactiveはサポートされていません。これは、GNU/Linux版Firefoxがプラットフォーム層として利用しているGTK側の制約に依るものです。

弊社でも「GNU/Linux版Firefoxでime-modeを使用することはできないか?」というお問い合わせを受けたことが過去に何度かあります。

ime-mode-we

最近、とあるお客様から「どうしてもこの機能をGNU/Linux版Firefoxで実現したい」という強いご要望があったため、新たにime-mode-weというアドオンを作成してお応えしました。

同アドオンは、今のところ多言語入力フレームワークとしてIBusを、入力エンジンとしてAnthyKKCMozcSKKのみをサポートしています。

インストール方法

アドオン自体は、通常のアドオンと同様に、同ページから「Firefoxへ追加」ボタンを押すだけでインストールすることができます。ただし、このアドオンはシステムネイティブのコマンドを呼び出す形で実装されているため、このネイティブコマンドについても別途インストールする必要があります。同ページにも記載していますが、以下の手順でネイティブコマンドをインストールして下さい

  1. "ime-mode-we-host.tar.gz"を https://github.com/clear-code/ime-mode-we/releases からダウンロードします。
  2. 以下のコマンドで、同アーカイブ内のファイルをシステムに展開します:
sudo tar xvf ime-mode-we-host.tar.gz -C /

アドオンの方をネイティブコマンドよりも先にインストールしてしまっている場合は、Firefoxを再起動して有効化して下さい。

なお、同コマンドの実行にはPythonが必要です。

利用方法

問題なくインストールが完了していれば、ime-mode: inactiveがセットされた入力エリアにフォーカスを合わせると自動的に入力モードが直接入力モードになり、ime-mode: activeがセットされた入力エリアにフォーカスを合わせると自動的に入力モードがひらがな入力モードに切り替わるようになります。後者については、実装上の都合で、直前の入力モードではなくひらがなモードに固定化されています(直前の入力モードに変更するためには、各IBusエンジン側の対応が必要です)。

ただし前述の通り対応している入力システムは限られますし、IBus側の設定をデフォルト状態から変更している場合には、対応済みのIBusエンジンでも正しく動作しないこともあるかもしれません。

まとめ

GNU/Linux版Firefoxでime-modeを動作させるアドオンime-mode-weを紹介しました。現在はIBusの特定のIMエンジンのみ対応していますが、Fcitxなどにも対応させることは難しくないでしょう。実際、上記のお客様向けには、非公開のプロプライエタリIMエンジンに対応させる形で提供していますし、IMエンジン側に手を入れることでひらがな固定といった制約も排除しています。また、ime-modeの仕様に拘らなければ、IMEのON/OFFだけでなく、初期状態をカタカナや半角カタカナなどに切り替えるといった機能も実現できるかと思います。

もしこういったカスタマイズのご要望がある場合は、ぜひ弊社お問い合わせフォームよりご連絡下さい。

2019-06-24

OSSへのフィードバックには何をどう書けばいいのか、どのプロジェクトに報告すればいいのか

※注:この記事の対象読者は、「OSSを使用していてトラブルに遭遇しているか、改善の提案があり、その情報を開発元のイシュートラッカーに伝えようとしているが、どんな内容を書けばよいかわからない」という人です。そもそも「どこに報告すればよいかわからない」「イシュートラッカーに書き込んでいいかどうか不安がある」という方は、1つ前の記事をご参照下さい。

結城です。

1つ前の記事では、フォーラムとイシュートラッカーのどちらに書き込めばよいかわからない場合の考え方について詳しく語りました。その際、両者の目的の違いを以下のようにまとめました。

  • フォーラム:個人の問題の解決を図る場所。
  • イシュートラッカー:ソフトウェアの問題の解決、品質の向上を図る場所。

この記事ではその続編として、イシュートラッカーの目的から導かれる「適切な、書くべき報告の内容」を語ってみます。

書くべき内容、避けるべき内容

フォーラムとイシュートラッカーの目的の違いは、「投稿する内容をどうまとめればよいのか」という事を考える時の指針にもなります。「ソフトウェアの問題の解決」を目的とするイシュートラッカーに報告する内容は、その目的に沿って、「ソフトウェアの開発に関わる人達が、このソフトウェアの問題を解決するには、どのような情報が必要か?」という視点で整理する事になります。

例えば、以下の3項目は典型的な「書くべき内容」です。

  • Steps to reproduce:現象の発生条件、再現に必要な手順
    • 他の人は、どうすればその現象が起こるかを知らないし、あなたが普段どのようにその機能を使っているのかも知らないので、あなたが詳しく説明するしかありません。
    • メニューの選び方、機能の呼び出し順序など、あなたが無意識でしている操作の仕方がその現象を引き起こす決定的なきっかけとなっているかもしれません。
  • Actual result:実際に起こる結果
    • 他の人は、自分の環境で得られた結果が、あなたの見ている物と同じかどうか分からないので、あなたが詳しく説明するしかありません。
  • Expected result:本来期待される結果
    • 他の人は、あなたほどにはその機能や使い方の事を詳しく知らないかもしれないので、あなたが詳しく説明した方が効率がよいです。

その問題のせいで自分がいかに困っているか? という訴えは報告のメインの内容とはなり得ません。プロジェクト全体の中でその問題の重要度の高さを認識してもらうための材料として、問題の影響度・深刻さの説明としてそれらの訴えを盛り込む場合はありますが、そのような訴え自体が問題の原因究明や修正箇所の特定に役立つという事は、基本的には無いからです。

重複する報告も、場違いな報告も、無駄じゃないのでしていい

しかし、いざ報告しようとしても、

  • 既に他の人が報告しているにもかかわらず、自分の探し方が下手なだけで、既存の報告を見つけられていないだけかもしれない。
  • この問題をこのプロジェクトに報告するのが適切かどうか分からない。もっと適したプロジェクトがあるかもしれない。場違いな報告をしたら迷惑かもしれない。

という心配から報告をためらう、という事例はワークショップの中でもよくあります。筆者はそのような場合には、「不安を感じるくらいなら、自分が思う内容・表現のままでそのプロジェクトに報告してしまってよい」とアドバイスする事が多いです。

既知の報告がないか全く調べていない、というのはさすがにまずいですが、自分の思いつく表現で検索して報告が見つからないなら、その表現で報告して大抵は問題ありません。なぜなら、仮にその後既知の他の報告と重複していると分かって、そちらに誘導された上でクローズされたとしても、その報告内容自体が、同じ探し方をする人のための今後の誘導になるからです。

適切な報告先プロジェクトかどうか分からない、という場合も同様です。その問題が根本的には別のソフトウェアの問題だったと後から分かっても、同様の現象に遭遇した人のための誘導になるので、報告は無駄にはなりません。例えば1つ前の記事で紹介した事例では、今後同様の現象に見舞われて検索して辿り着いた人は、今後はMicrosoft IMEの動向に注意するとよい、という情報を得られる事になります。

また、根本的な原因については既に報告があったとしても、その報告で触れられている以外の現象の情報があると、それは問題の影響度合いを示す情報になります。当初の報告では些細な問題だから後回しにしようと判断されていた物が、実はユーザーレベルで大きな影響を受ける物だったと分かって、対応の重要度・緊急度が引き上げられるという事は度々あります。

却下された報告や提案にも価値がある

明らかな不具合というよりは「こうなっているとより良い」という提案の性質が強い報告の場合に多いのですが、「それは対応しない」「やらない」と判断され却下される場合もあります。そのような場合も、「無駄だった」「失敗した」という考え方をする必要はありません。というのも、「ある提案が却下された」という事そのものにも意義があるからです。

OSSのプロジェクトのスコープ*1は、必ずしもすべて明確化されているとは限りません。ある人にとっては「当然あるべき」と思える機能が無かったり、逆に、「無駄にしか思えない」という機能があったり、特に、それについて何の説明も無いという事はざらにあります。大規模なプロジェクトでは、すでに参加している人の間ですら解釈が別れていたりもします。

しかし、例えスコープが明文化されていなくても、一貫性を持った数々の判断の結果、その輪郭は段々と浮かび上がってきます。新たな判断の事例が1つ増えるという事は、不明瞭だった基準がより明確化されたという事になり、後から来た人にとって有用な情報となります。また、判断と共にその根拠が示されていれば、後になって状況が変わり根拠が薄れた時などに、それを理由として再考を求める事もできます。

そのような意義ある判断を引き出すためにも、議論は「自分の意見を押し通すため」ではなく「プロジェクトの目的をより良く達成するため」という点を念頭に置いて、「相手(敵) v.s. 自分」ではなく「問題 v.s. プロジェクト」という方向で行いましょう。反論も、主張の材料を補ったり、説明しきれていなかった理由を追加で説明したりと、意味のある反論をする事が肝要です。感情的に同じフレーズを繰り返すだけや、明確な根拠無しに強弁するだけのような不誠実な態度、他の参加者の共感を得られないゴリ押しは、百害あって一利無しです。

ただし、実際に手を動かす人が足りないから労力的に対応できないという理由で却下される場合は、より深く関わるチャンスです。自分で実装してパッチ(プルリクエスト)を提出し、その後もメンテナンスを引き受け続ければ、あなたも立派に開発者の仲間入りという訳です。

「対案」無しでも報告・提案していい

  • 報告だけでは無責任なのではないか? 対案まで考えてから出さないと駄目なんじゃないか?
  • パッチ(プルリクエスト)まで書いて初めてOSS開発への参加と言えるんじゃないか?

といった点で悩んで報告をためらう、というケースもあります。筆者はこのような場合、「対案は無くてもいいから、まず報告してみよう」とアドバイスします。

もちろん、コードのレベルで修正の仕方まではっきり分かっているのなら、パッチやプルリクエストの形でフィードバックできるに越した事はないです。しかし、そうできないならフィードバックしない方がよい、という事はありません。

むしろ、自分の考えつく解決策が最良であるとは必ずしも限りません。詳しい事情が分かっていない段階で自分の思い込みだけで独りよがりに実装を作り込んでしまうと、その労力がまるっきり無駄になるという事もあり得ます。例えば、ある機能の不具合を見つけて、その問題を解消するための複雑な変更を持ち込んだが、単にその機能全体を既存の別ライブラリで置き換えれば済む事だった、というような事はよくあります。筆者も、過去に強引な実装のパッチを代理で投稿してもらった事がありましたが、実装の筋が悪すぎたためか、それ以上話が進む事はありませんでした。

イシュートラッカーは「問題の解決」に取り組むための場であって、「特定の解決策の実現」に取り組む場ではありません。解決策は関わる人みんなで考えてよく、一人で抱え込む必要はないのです。よく「文句を言うなら対案を示すべき」という言い方がされますが、だからといって「対案が無いなら文句を言ってはならない」は真ではありません。問題解決に取り組む1つのチームの一員として、対案を考える事も含めて皆で取り組む、という姿勢・考え方をするのがポイントです。

同じ問題に取り組む仲間と思って接しよう

真摯に議論しようという話とも共通しますが、「問題を解決する開発者達 v.s. 外部から善意で協力しているただのユーザーの自分」という壁を自ら作る事は避けた方がよいです。対等な関係ではないという事を過剰に意識してしまうと、実際以上に大きな上下関係を自分の中に作り上げてしまい、コミュニケーションの妨げになります。

1つ前の記事ではOSSに新たに関わる人を新入社員に例えましたが、そう考えれば、なぜ自分とプロジェクトの間に過度に壁を作るべきでないのかが分かるのではないでしょうか。新メンバーがお客様気分で上げ膳据え膳に期待してふんぞり返るのはおかしいですし、かといってへりくだりすぎるのもおかしいですよね。

無論、雇用されフルタイムで開発に従事している人と、外部から余力の範囲で関わっている人の間では、立場も権限も異なります。しかし、そのプロジェクトの目的、あるいは報告した1つの問題の解決に向けて一緒に取り組む仲間という点では差は無いはずですから、お互いに敬意を持って接する事が大事です。

特に、「自分は問題で損をした被害者なんだ。その被害者自身がわざわざ協力してやってるんだ。だからお膳立てはあいつらの方で整えてくれて然るべき」というような捉え方は、問題の解決を遠のけさせこそすれ、近づけさせは決してしません。このような意識を強く持ってしまうと、相手の無理解を責めたり相手をやり込めたりする事にばかり意識が向いてしまい、ひいては特定個人に対する罵倒や中傷にまでエスカレートし得ます*2

まとめ

以上、OSSにフィードバックする事に不慣れな場合に悩みがち・判断に迷いがちと思われる点について、イシュートラッカーの目的から導かれる「適切な考え方」を、筆者の感覚から語ってみました。

表現を変えながら繰り返し何度か述べていますが、OSS開発に関わる際は基本的に「問題 v.s. それに立ち向かうプロジェクト参加者達(そして、その一員としての新人の自分)」という構図で考え取り組む事が大事だというのが、筆者の考えです。かつては思ったように成果を出せなかった自分も、そのように考えられるようになって以降は、より有用な報告ができ、提出したパッチやプルリクエストを取り込んでもらえる機会も増えたように思います。まだOSSの開発への参加に不慣れで、報告がうまくいかなくて悩んでいるという方は、この記事で述べた点を意識してみてはいかがでしょうか?

また、この記事で述べた事は実際にはOSSに特有の話ではなく、一般的に企業内でバグ票をやり取りするような場合にも共通して言える事です。1つ前の記事ではOSSのイシュートラッカーを出入り自由の社屋や工場に例えましたが、OSS開発の場で広く共有されているノウハウの中には、普通に仕事の上で有用な物も多く含まれています。特に、OSS開発では「多くの人を雇って人海戦術で乗り切る」というような力業での解決が難しいため、いかに少ないコストで最大の効用を得るかという点で工夫がなされている事も多いです。当社のOSS開発支援サービスでは、OSS開発に参加していきたいという企業さまのお手伝いだけでなく、OSSコミュニティでの開発ノウハウを企業内での開発に活かすお手伝いも承っています。そういった事に関心をお持ちの担当者さまがいらっしゃいましたら、ぜひお問い合わせフォームよりご連絡下さい。

*1 プロジェクトとして取り組む事の範囲。

*2 お恥ずかしい話ですが、筆者も何度かこれで失敗しています。

2019-06-19

OSSへのフィードバックはユーザーフォーラムとイシュートラッカーのどちらに書くべきか?

※注:この記事の対象読者は、「OSSを使用していてトラブルに遭遇しているか、改善の提案があり、その情報を開発元に伝えたいが、どこで伝えればよいかわからない」という人です。「どういう体裁で報告すればよいか分からない」「何を報告すればよいか分からない」という人向けの話はまた日を改めて書くつもりです。

結城です。

OSS Gateワークショップで、初めてフィードバックをしようとしているビギナー参加者のサポートをしていると、ビギナー参加者から以下のような質問を受ける事があります。

  • こんな簡単な・くだらないレベルの事を報告してもいいんでしょうか?
  • ユーザーフォーラムとイシュートラッカー(バグトラッキングシステム)*1のどちらに報告すればいいんでしょうか?
  • どのプロジェクト(開発元)に報告すればいいんでしょうか?

これらの点に対する筆者の回答は、端的には以下のようになります。

  • 簡単でも些細でも何でも、あらゆる未解決の問題は報告していい。
  • これは自分個人の問題ではなく、そのソフトウェアの全ユーザー向けに解決されるべき問題だ、と思えるならイシュートラッカーに報告していい。
  • 自分で確かめられる範囲ではこのプロダクトの上でしか問題に遭遇しない、他のプロダクトでは問題が再現しない、と言えるならとりあえずその開発元に報告していい。

奇しくも最近、これらの事を考える上で非常に興味深い事例に出会いました。以下、それを題材として上記の点をどのように判断しているのかを語ってみます。

報告者からフォーラムへ、フォーラムからイシュートラッカーへ、MozillaからMicrosoftへ

当社の法人向けのThunderbirdサポートにおいて、数ヶ月前から複数のお客さまより「メール作成時に日本語入力で漢字への変換ができなくなる」という現象のお問い合わせを頂くという事がありました。

お問い合わせの中にはMozillaZineフォーラムに同様の事例の報告がある旨をお書き添え頂いた物もあり、参照してみると、スレッドの大まかな流れは以下のようになっていました。

  1. このような現象が起こっている、既知の解決策はどれも有効でなかった、という情報が投稿される。(2018年12月末)
  2. 現象の再現条件の特定が複数人によって進められる。(2018年12月末~1月頭)
  3. Thunderbirdに対して行われた変更のうち、どの変更以降からこの現象が起こるようになったのかが特定される。(2019年1月)
  4. 暫定的な回避作として、このアドオンをインストールすると現象が起こらなくなる、という情報が寄せられる。(2019年1月末~2月)

当社の検証環境でも、条件が整うと確かに現象が再現するという事を確認できました。そこで、Mozillaが製品開発のために運用しているイシュートラッカーであるBugzillaに何か情報が無いかと検索してみたのですが、思いつく限りのキーワードで検索しても該当するBugを見つけられませんでした。そのため、ひとまず筆者自身で新しいBugとして報告を行いました。これが2019年5月の事です。

もし既に報告されている問題であれば、そちらへの参照情報が追加され、この新しいBugは「重複する報告」としてクローズされます。しかし実際にはこれが最初の報告だったようで、最終的にはFirefoxとThunderbirdの共通基盤であるGeckoエンジンの日本語入力部分の担当であるMozillaの中野さんにまで連絡が行くという事にまでなりました*2

ただ、話はそれで終わりませんでした。仮にこれがGeckoの明白なミスに起因する現象だったのであれば、Gecko側で修正されてBugはクローズされます。しかし実際には、Mozillaの中野さんによる詳細な調査ではGecko側に問題は見当たらなかったため、Microsoft IME(MS-IME)側の不具合である可能性があるとして、中野さんからMicrosoftのフィードバック窓口へ2019年5月末に報告されたそうです。

以上が、この件の2019年5月末時点の状況です。

ずっと以前から現象が確認されていても全く進展が無かったのが、イシュートラッカーに報告された途端に事態が動き出す、という事は度々あります。上記の経緯のうち、フォーラムからBugzillaへの報告までの流れはまさにそのような推移に見えます。

しかし最終的な結果を見ると、Thunderbirdの問題でなくMicrosoft IMEの問題である可能性があるなら、MozillaのイシュートラッカーであるBugzillaではなくMicrosoftに報告するのが正しかったのではないか? という見方もできます。もし仮に本当にMicrosoft IMEの問題だったのであれば、現象の確認から適切な場へ情報が伝わるまでに半年もの時間がかかってしまったという事になります。

さて、この問題は一体どのように取り扱われるべきだったのでしょうか?

誰の問題か、何をしたいかという観点で持ち込み先は変わる

ここまでの経緯には多数の論点が入り交じっていますが、目的・動機という点では大まかに以下の2つにまとめられます。

  • 報告者にとっての「どうすれば自分が今困っているこの状況を脱せるのか?」という視点=個人の問題を解決したいという視点
  • 開発者にとっての「そのソフトウェアにどんな問題があるのか、解決されるべき問題はどんな内容なのか」という視点=ソフトウェアの問題を解決したいという視点

ソフトウェアの問題が解決された結果として個人の問題が解決されるという事も、個人の問題を解決するためにした事が結果的にソフトウェアの改善にもなるという事もあります。しかし、それらはあくまで偶然の結果そうなっただけで、最初から偶然に期待するというのは効率が悪くお薦めできません。

OSSでは、というよりもこれは人間社会で一般的に言える事ですが、報告・投稿を持ち込む先は目的によって決めるものです。問題がいつまでも解決されない場合、最大の原因は問題を持ち込んだ先が適切でなかったからだった、という事がよくあります。

フォーラムが解決できる問題

上記の「フォーラムに報告がなされた例」では、関わった人達の期待とその結果は以下のように言えます。

  • トラブルに遭遇した本人(フォーラムに最初に投稿した人)にとって:
    • 期待:
      • 自分が遭遇した問題の解決。
    • 結果:
      • フォーラムに集う人達に調べて貰えて、発生条件を絞り込めた。
      • その人固有の状況で有効な暫定的回避策が判明し、当座をしのげるようになった。
  • フォーラムに集う人達にとって:
    • 期待:
      • 相談者によって持ち込まれた問題の解決の手助け。
    • 結果:
      • 助けを求めてやってきた人の問題の解決に力を貸せた。
  • その後同様の問題に躓いた人達にとって:
    • 期待:
      • 問題にそもそも遭遇しない事
    • 結果:
      • ソフトウェアの問題は未解決のままだったので、同じ現象に後から遭遇してしまった
      • フォーラムの投稿者と状況が一致していれば、暫定的解決策で現象を回避できる。
      • フォーラムの投稿者と状況が一致しないと、暫定的解決策では現象を回避できない
  • ソフトウェアの開発・品質向上に関わる人達にとって:
    • 期待:
      • ソフトウェアの開発が進む事、品質が向上する事。
    • 結果:
      • 普段見ていない場所で話が進行していたので、問題の存在自体を把握できなかった
      • 問題が把握されなかったため、対応もなされなかった

このように、個々のトラブルの解決や、同様のトラブルに遭遇した人の解決のための情報源にはなるものの、同様のトラブルが繰り返される事そのものの解決にまではならないのが、ユーザーフォーラムの性質と言えます。

また、ユーザーフォーラムは「ユーザー同士の相互扶助の場所」であるという点にも注意が必要です。基本的にはボランティア運営なので、分かる人がいなければ反応を得られないという事もあります。そこに集まる人は全く無関係の人よりは詳しい人である可能性が高いですが、開発者ほどには詳しくない場合も多いです*3

イシュートラッカーが解決できる問題

では仮に、最初から問題をイシュートラッカーに投稿しようとしていたら何が起こったでしょうか。筆者の見立てでは、最悪の場合の結果は以下のようになったのではないかと考えています。

  • トラブルに遭遇した本人や、同様の問題に躓いた人達にとって:
    • 問題の原因調査の方法に詳しくないと、有用な情報を提供できない。
    • そもそも技術的な知識の有無以前に、英語が不得意だと、自分の置かれた状況(問題の発生条件)を上手く説明できない。
    • 原因が特定され、次のバージョンで修正されても、今使っているバージョンでの問題は解決しない
    • 調査の過程で暫定的な解決策がたまたま見つからなければ、今この瞬間のトラブルは解決しない
  • ソフトウェアの開発・品質向上に関わる人達にとって:
    • 調査方法を知らない・開発者レベルの知識が無い人に調査の仕方を説明するために、時間と手間を使う必要がある。
    • 有効な情報を得られないと、スッキリしないものを抱えたままになる。

一方、もし理想的に推移したとすると、以下のようになるでしょう。

  • トラブルに遭遇した本人や、同様の問題に躓いた人達にとって:
    • 原因が特定され、次のバージョンで修正される事になれば、そのバージョンのリリースを待てば問題は解決する。
    • しかし、今使っているバージョンでは問題は解決しない
    • 調査の過程で暫定的な解決策がたまたま見つからなければ、今この瞬間のトラブルは解決しない
  • ソフトウェアの開発・品質向上に関わる人達にとって:
    • 問題の原因を特定できれば、根本的解決や回避策を検討できる。
    • その成果を次のバージョンに盛り込めれば、同様のトラブルの発生を防げる。
    • 根本的な原因がそのソフトウェアに無いとしても、より適切な場所へ、開発者レベルでの詳細な調査結果を報告できる。

いずれの場合も、今この瞬間に起こっている問題の解決には必ずしもつながらないし、また、その優先順位も低い、という事には注意が必要です。

イシュートラッカーに関わる人には、ある程度の知識が要求されます。報告者に全く知識が無いという場合、問題自体の深刻度がよほど高いと判断されれば、開発者もなんとか原因究明に必要な情報を報告者から引き出そうとして手厚く手助けする事もあります。しかし、それだけの手間をかけるのは割に合わないとなれば、残念ながらそれ以上の手助けはなされません。

このような事になるのは、OSSプロジェクトのイシュートラッカーは「個人の問題を解決する場所」ではなく、あくまで「ソフトウェアの開発を進め品質を向上する事を目的とする場所」だからです。

ソフトウェアの改善・ソフトウェアの問題の解決に関わりたいならイシュートラッカーへ

例えて言えば、これは企業の社屋や工場に誰でも出入り自由になっている状況のようなものです。社会科見学では見学しかできないのに対し、見学ルートを外れて「中の人達」同士の議論に混ざって発言できる、参加の機会が開かれているのがOSSです。そう考えれば、そこで行われている議論や開発に誰でも気軽についていける訳ではなく、機会があるかどうかとその中で一人前の参加者として振る舞えるかどうかは別の話だ、という事も納得しやすいでしょう。

しかし、これは言い換えれば、開発に関わりたい・品質向上に寄与したいという積極的な意志を持つ人にとっての門戸が開かれているという事です。開発の拠点が海外でも、普段の仕事がソフトウェア開発と無関係でも*4、あるいはライバル製品の開発元に所属していてすらも*5、やる気次第で自分から参入できます。

  • 「ここの所に穴が開いてるみたいなんだけど、大丈夫かなあ……塞がれないのかなあ……? 気になる……」「この機能のこの部分、これだと不十分に見えるんだけどなあ……ソワソワする……」という風に、ソフトウェアのちょっとした不具合が気になって仕方ない人。
  • 「ああもう! この人達(開発者)はまるで分かってない! 俺の方がずっとスマートにこの問題を解決できるのに!」「ああもう! なんでここの所はこんな風にできてるんだ? 使いにくい! 俺ならこんな作り方にしないのに!」という風に、問題が放置されている事に我慢がならない人*6

こういったモヤモヤを感じた時に、「でも、手を出せないんだからしょうがない」と諦めないで根本的解決できる可能性が開かれているのがOSSなのです。

ですから、「OSS開発に関わってみたい、ソフトウェアの改善に関わりたい、その最初の一歩を踏み出してみたい」と思ってOSS Gateワークショップに参加を考えた人であれば、もうその時点で「イシュートラッカーに報告する」という選択をして全く問題ない訳です。

また、その際には最初から理想的に振る舞える必要はありません。OSSプロジェクトに初めて関わる人というのは会社の新入社員と同じですから、当然要領は良くありませんし、最初は簡単な仕事からしかこなせませんし、あるいはミスもします。分からない事があれば、会社の先輩に質問するのと同じように、先に参加していた人を捕まえて質問するだけの事です。

「フォーラムに書くべきか、イシュートラッカーに書くべきか」「こんな些細な問題を報告してもいいのか」という問いへの筆者の答えが「個人の問題でないならイシュートラッカーに書いてよい」「些細でも報告してよい」となるのは、以上のような理由からです。

まとめ

以上、OSS Gateワークショップの中で度々聞かれる「フォーラムとイシュートラッカーのどちらに書くべきか判断できない」という悩みについて、フォーラムとイシュートラッカーの目的を把握した上で、「ソフトウェアの問題を解決する場所」というイシュートラッカーの目的に沿った報告をすればよい、という事を語ってみました。

イシュートラッカーへの報告は、問題が解決されればより多くの人に恩恵がもたらされます*7。OSSのイシュートラッカーはソフトウェア開発の現場ですので、ソフトウェア開発の知識がある人はよりよい報告ができる可能性がありますし、パッチやプルリクエストを通じて直接的に問題解決を図る事もできます。一歩進んだ関わり方として、皆さんもイシュートラッカーへの報告にぜひ挑戦してみて下さい。

ところで、先の事例にはもう1つ気になる点が残っています。それは、Microsoft IMEの問題だった可能性があるのにThunderbirdの問題として報告してしまってよかったのか、自分では適切な判断ができない時は一体どこに報告すればよいのか、という点です。次の記事では、それも含めて「どんな報告の仕方をすればいいか、報告の内容はどう書けばよいか」について語ってみます。

なお、当社ではOSS開発を推進したい企業さまのお手伝いをするOSS開発支援サービスを行っています(直近のアカツキさまでの事例の紹介)。社内のITエンジニアのOSS開発者としての活躍を促進したいとお考えの担当者さまがいらっしゃいましたら、ぜひお問い合わせフォームよりご連絡下さい。

*1 「ソフトウェアの不具合」を「バグ」と呼ぶことから、バグの修正状況の追跡をする物として「バグトラッキングシステム(Bug Tracking System、BTS)」という呼び方が以前はよく使われていました。しかし、この呼び方だと「不具合ではないただの要望はバグとして取り扱うべきなのかどうなのか?」という点で混乱が生じる場合があります。Mozillaが運用するバグトラッキングシステム「Bugzilla」では、不具合報告だけでなく要望もすべてひっくるめて「バグ」と呼ぶという運用ルールにする事でこの混乱を回避していますが、運用ルールを知らない人にとっては違和感が残ります。そのため現在は一般的には、バグや要望などを「解決されるべき課題=issue」と捉えて「イシュートラッキングシステム(Issue Tracking System、ITS)」や「イシュートラッカー」と呼んだり、あるいは、どんな課題であってもシステム上で管理される時はひとつの「チケット」になるからという事で「チケットトラッキングシステム」と呼んだりします。本稿では、ひとまず「イシュートラッカー」で統一しています。

*2 またその過程で、`intl.tsf.enable`という設定の値を`false`に変更すると現象が解消されるという、別の暫定的解決策も紹介されていました。これはWindows XP以降で標準となっている文字入力の仕組みを使うかどうかを制御する設定で、`false`に設定すると従来の文字入力の仕組みを使うようになります。音声からの文字入力などTSFで初めて可能になった事はできなくなりますが、その状態でも、キーボードからの一般的な文字入力操作に関しては特に支障なく行えます。

*3 これに対し、当社の法人向け有償サポートサービスは、ソースコードレベルの調査を実施したり、一定の期限内で回答したり、という事をお約束する事をもって対価を頂いているという事になります。

*4 ソフトウェア開発ではなく運用に従事しているという人や、まだ就職していなくて学生で開発に参加する人もいます。

*5 実際に、Mozillaに雇用されている人達もChromiumにバグ報告をしています。

*6 「プログラマーの三大美徳」の1つの「傲慢」とは、このような事(自分にはこの問題を解決できるはず、という考え方をすること)を指します。

*7 当社の法人向けサポートサービスは、お客様の問題(個別の問題)について原因や回避方法を調査してその解決を図ると同時に、その問題がソフトウェアの問題であった場合はソフトウェアの品質向上のためアップストリームへのフィードバックも行う事を心がけています。

2019-06-18

代表取締役の須藤がApache Arrowの開発でGoogle Open Source Peer Bonusを受賞

Apache Arrowの開発に参加している代表取締役の須藤です。

もう2ヶ月前の話なのですが、2019年のGoogle Open Source Peer Bonusの1人に選ばれました。選ばれるまでこんな取り組みがあることを知らなかったのですが、2011年からやっているそうです。オープンソースの開発に関わっている人を支援する取り組みだそうです。賞金(?)として250ドルもらいました。ありがとうございます。

Apache Arrowの開発をがんばっているということで選んでもらいました。現時点で私は2番目にコミット数が多いのでそのあたりを評価してくれたのかもしれません。ちなみに、1番コミット数が多いWesさんはpandasの開発で選ばれていました。

私の自由なソフトウェアの開発を支援したいけどどう支援したらよいかわからないという方はご相談ください。

2019-06-17

Firefox 67以降のユーザープロファイルの仕様の詳細

Firefox 67の新機能の1つに、インストール先ごとにプロファイルが分けられるようになったという物があります。

この記事では、Firefoxのユーザープロファイルの仕組みの歴史的な経緯や、プロファイル切り替えの仕組み自体がどのように使われてきたかという点を踏まえながら、Firefox 67での新機能の性質を解説します。

Firefoxの「ユーザープロファイル」

Firefoxのユーザープロファイルの仕組みは、元を辿ると、その前身となったNetscape Communicatorのユーザープロファイルの仕組みに行き着きます。

Netscape Communicatorが現役だった頃に広く使われていたWindows 95やWindows 98は、原則としてユーザーは1人だけであるという前提で設計されていたため、複数人で同じPCを共用する場合にユーザーを使い分けるという事ができませんでした。そのためNetscape Communicator独自の概念として「使用者ごとにユーザープロファイルを作り分けて、設定値やブックマークなどはその中で管理する」という仕組みが用意されました。

(図:Netscape Communicatorのユーザープロファイルをユーザーごとに使い分ける様子)

その一方で、Windows XP以降のバージョン*1ではOS自体が複数ユーザーを想定した設計になっています。アプリケーション側で個別にユーザープロファイルを管理する必要は無く、アプリケーションの設定を使用者ごとに使い分けたい場合、単純にWindowsのユーザーを使い分ければよいという事になっています。

(図:Windowsのプロファイルをユーザーごとに使い分ける様子)

以上のような歴史的な経緯があり、Firefoxのユーザープロファイルは「Windowsのユーザープロファイルごとに、複数のFirefoxのプロファイルが存在しうる」という少々複雑な状況となっています。

(図:Windowsのプロファイル上に複数のFirefoxのプロファイルが存在する様子)

実際には、Windowsのユーザーを使い分ければよい現状においては、使用者ごとにFirefoxのプロファイルを使い分けないといけないという状況はまず発生しません。よって、Firefoxのユーザープロファイルは今では1人のユーザーが、「仕事用」「開発用」「趣味用」といった何らかの用途ごとに使い分けるという用途が主流になっています。

(図:Windowsのプロファイル上で、用途ごとにFirefoxのプロファイルが使い分けられている様子)

「ユーザープロファイルの使い分け」から「コンテキストやコンテナーの使い分け」への変化

ただ、一般的なユーザーが普段使いにおいてFirefoxのユーザープロファイルを使い分けるということは、実際にはあまり無いものと思われます。その最大の理由は、運用の面倒さです。

Firefoxのユーザープロファイルを使い分けるには、

  • Firefoxの起動オプションに-pオプションを指定してプロファイルマネージャを起動し、そこでプロファイルを管理する。
  • about:profilesでプロファイルを管理する。

このいずれかの方法でプロファイルを作成し、さらに、

  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p private(個人的な使用)
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p work(仕事での使用)
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p test(検証用)

のように起動オプションを変えたショートカットを複数用意する必要があります。

また、これだけでは「個人用のFirefox」「仕事用のFirefox」を並行して起動することができません。というのも、Firefoxのプロセスが既に起動している場合、別のプロセスで新たにFirefoxを起動しようとすると、既に起動している方のプロセスの方にプロセスが吸収されてしまう(そちらでウィンドウやタブが開かれる)という結果になるからです。これを回避するためには、

  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p private
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p work -no-remote
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p test -no-remote

のように、普段使いの(URLなどの関連付けからFirefoxが起動された時に使う)プロファイルを除いて他のショートカットには-no-remoteオプションを指定し、前述の「既存プロセスに吸収される」挙動を無効化する必要があります。

また別の方法として、プロファイルマネージャを使用せずに以下のようにする方法もあります。

  • "C:\Program Files\Mozilla Firefox\firefox.exe" -profile "C:\Users\username\private-profile" -no-remote

-profileオプションで任意のフォルダをフルパスで指定すると、プロファイルマネージャの管理下にないフォルダであっても、それをプロファイルとしてFirefoxを起動できます。実験や検証のためのプロファイルをいくつも併用したり使い捨てにしたりという使い方をしたい場合、プロファイルマネージャを使わずともフォルダを用意するだけで済むため、この方法は非常に便利です。ただしこの場合も、-no-remoteを付けないと「既に起動している方のプロセスの方にプロセスが吸収される」という動作になってしまう点には注意が必要です。

これだけ面倒な手順が必要なわりに、一般的なユーザーが普段使いで得られるユーザー体験はあまり良い物ではありません。というのも、実際の利用局面では「仕事中に見つけた面白そうな記事を個人用にブックマークしておく」「個人的な使用中に見つけた仕事に関係する記事を、仕事中に履歴から探す」といった場面が生じやすいのに対し、履歴やブックマークなどがプロファイルごとに別々に保存されていると、そういった「用途をまたいだ情報の共有」ができないからです。

この問題の解決策として現在のFirefoxには、「1つのユーザープロファイルで、閲覧履歴やブックマークなどは共有しつつ、起動中の1つのプロセスの中でログイン状態やCookieなどの認証情報は分離する」という事を可能にする、以下の機能が備わっています。

  • プライベートウィンドウ(そのウィンドウの中で閲覧したページには、通常モードで閲覧した時のCookieなどが通知されない)
  • コンテナータブ(用途ごとに認証情報を切り替える)

これらの機能は、「諸々の不便を被ってでも厳密にプロファイルを分けたい程ではない」「しかし、ログイン状態やCookieなどの認証情報は用途ごとに切り替えたい」という、実際の使用局面でよく見られるニーズに応えるものとなっています。

(図:コンテナーを使い分けている様子)

ユーザープロファイルの使い分けよりもはるかに手軽に使えるため、これらの機能で充分に用を果たせる場面では、ユーザープロファイルの使い分けのニーズはほぼ無くなったと言ってよいでしょう。

それでも残った「ユーザープロファイルを使い分ける必要がある場面」

以上のような経緯から、現在のFirefoxで「ユーザープロファイルを使い分けなければその目的を達成できない」場面は非常に限られています。その代表的な例が、複数バージョンのFirefoxの並行起動です。

(図:複数バージョンのFirefoxを専用プロファイルで使い分けている様子)

例えば、前述の手順を用いて複数バージョンのFirefoxを並行起動する場合、以下のように起動オプションでプロファイルを指定する事になります。

  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p default(64bit版Firefox)
  • "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -p 32bit -no-remote(32bit版Firefox)
  • "C:\Program Files\Mozilla Firefox Beta\firefox.exe" -p beta -no-remote(ベータ版)

Firefox 67からの変更は、まさにこの用途のためのものです。言い換えると、Firefox 67以降のバージョンでは、「インストール先が異なるFirefoxの実行ファイルごとに、専用のユーザープロファイルを使用する」使い方が、特にユーザー側での工夫無しに自動的に行われるようになっているという事になります。

Firefoxが自身のインストール先を識別する処理の流れ

では、このような挙動は一体どのようにして実現されているのでしょうか。特に、「特定のインストール先のFirefox」と「特定のユーザープロファイル」とはどのように紐付けられているのでしょうか。鍵になるのは、インストール先のパスに基づくCity Hash値です。

Firefox 67以降のバージョンでは、Firefoxはプロセスの起動時に、自身の実行ファイルが置かれたフォルダの位置からCity Hashのアルゴリズムに基づいてハッシュ値を求めます。例えばFirefoxがC:\Program Files\Mozilla Firefoxにインストールされていた場合、値は308046B0AF4A39CBのようになります。内部的にはこれは「install hash」と名付けられている模様です。

次にFirefoxは、ユーザープロファイルが置かれている%AppData%\Mozilla\Firefox(具体的には C:\Users\ユーザー名\Appdata\Roaming\Mozilla\Firefox)の位置にあるprofiles.iniから[Install(install hash)]という名前のセクションを探します。これは通常、以下のような内容になっています*2

; こちらは従来からあるセクション
[Profile0]
Name=default
IsRelative=1
Path=Profiles/xxxxx.default

; 自動的に追加されたセクション
[Install308046B0AF4A39CB]
Default=Profiles/xxxxx.default
Locked=1

このDefaultの値がprofiles.iniから見た相対パスとなっており、このパスを解決することで、特定のインストール先のFirefoxに対して紐付けられたプロファイルフォルダを特定できるというわけです。この仕組みがあるお陰で、関連付け等からFirefoxが起動された場合などで起動オプションでプロファイルが明示されていなくても、適切なプロファイルが自動的に選択されるようになっています。

ただし、同じインストール先であっても、起動時のパスの指定の仕方によってはプロファイルが意図せず切り替わってしまう場合があります(別記事にて詳細な解説)。Firefoxのパスを明示的に指定する場面では、必ず正式なパス表記を使うように注意して下さい。

なお、この機能について「Firefoxのバージョンごとにプロファイルが別れる」というような説明がなされている場合がありますが、以上の仕組みを見て分かる通り、プロファイルはあくまでFirefoxのインストール先のパスに紐付いています。インストール済みのFirefoxに別のバージョンのFirefoxを上書きインストールしたり、Firefox自身の自動更新機能で新しいバージョンに更新したりした場合であっても、Firefoxのインストール先が変わらなければ、プロファイルは以前の物が引き続き使われます。「Firefoxを更新したらその度に新しいプロファイルが作られる」という事はありません。(逆に言うと、この機能を使ってプロファイルを使い分けるためには、必ずそれぞれのバージョンのFirefoxを別々の位置にインストールする必要があります。)

Windowsのレジストリ上での取り扱い

上記のinstall hashはWindowsのレジストリ上でも使われています。

従来は、Windowsのレジストリ上はFirefoxはあくまで「Firefox」という名前の1つのアプリケーションとして扱われており、複数のバージョンを異なるフォルダにインストールした場合は最後にインストールした物(最後にインストーラがレジストリに書き込みを行ったバージョン)がその代表として扱われるようになっていました。例えばシステム標準のブラウザの選択肢の項目は

  • HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\Firefox
  • HKEY_CURRENT_USER\Software\Clients\StartMenuInternet\Firefox

とその配下に記録された情報に基づいて表示されていました。

Firefox 67以降のバージョンでは、この情報がインストール先ごとに書き込まれるようになっています。

  • HKEY_LOCAL_MACHINE\SOFTWARE\Clients\StartMenuInternet\Firefox-(install hash)
  • HKEY_CURRENT_USER\Software\Clients\StartMenuInternet\Firefox-(install hash)

同様に、関連付け対象のファイルやデータの型も

  • HKEY_CLASSES_ROOT\FirefoxHTML-(install hash)
  • HKEY_CLASSES_ROOT\FirefoxURL-(install hash)

のようにそれぞれインストール先ごとに登録されるようになりました。このように、Windowsのレジストリ上はインストール先ごとのFirefoxはそれぞれ別々のアプリケーションとして認識されています

アプリケーションの一覧上でそれぞれのインストール先を識別できない問題の回避策

以上の通り、Windowsのシステム上は各インストール先のFirefoxは別々の物として認識されているわけですが、ここで1つ問題があります。内部的にはそれぞれ別々のinstall hashを伴って認識されているものの、表示されるアプリケーション名としてはどれも「Firefox」となるため、標準のブラウザや関連付けの対象を選択する場面で同じ名前の項目がいくつも並んでしまうという事が起こってしまうのです。

(複数のバージョンのFirefoxが同じ名前で並んでいる様子)

現在の所、この問題を解決するには手動でのレジストリの編集が必要です。この一覧に表示されるアプリケーション名は HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\MuiCache というキーの値が参照されており、

  • C:\Program Files\Mozilla Firefox\firefox.exe.FriendlyAppName のデータ→Firefox Release
  • C:\Program Files\Mozilla Firefox ESR\firefox.exe.FriendlyAppName のデータ→Firefox ESR

のように実行ファイルのパス.FriendlyAppNameという名前の値のデータをそれぞれ編集しておくと、インストール先ごとの項目が分かりやすい名前で表示されるようになります。

(複数のバージョンのFirefoxにそれぞれ別の名前が付いている様子)

起動オプションの作用はどう変わったか

上記の通り、Firefox 67以降のバージョンは自分自身のインストール先に基づいて適切なプロファイルを自動的に選択するようになったわけですが、では、今まで使われていた「起動オプションでプロファイルを明示する」機能はどのような影響を受けたのでしょうか。

-p プロファイル名

前述した通り、Firefox 67以降のバージョンでは%AppData%\Mozilla\Firefox\profiles.iniに以下のように[Install(install hash)]という名前のセクションが追加されます。

; 従来からあるセクション
[Profile0]
Name=default
IsRelative=1
Path=Profiles/xxxxx.default

; 自動的に追加されたセクション
[Install308046B0AF4A39CB]
Default=Profiles/xxxxx.default
Locked=1

この時、2つのセクションで同じパスが参照されている点に注目して下さい。Firefoxは参照先のパスが一致する2つのセクションを関連付けて認識しています。そのため、以下の2つのコマンド列は同等として扱われます

  • "C:\Program Files\Mozilla Firefox\firefox.exe" (install hashに基づいて自動的にプロファイルを選択)
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p default-pオプションでプロファイルを明示)

引数無しで起動したFirefoxのプロセスがある状態でプロファイルを明示してFirefoxを起動しても、逆に、プロファイルを明示して起動したプロセスがある状態で引数無しでFirefoxを起動しても、既に起動している方のプロセスに処理が吸収される(既存プロセスの方でウィンドウまたはタブが開かれる)という、従来の-no-remoteオプション無しの動作と似た結果になります。

同じバージョン・同じインストール先のFirefoxを、別プロセス・別プロファイルで起動する

別のプロファイルを指定して別のプロセスを並行動作させたい場合、従来は-p 別のプロファイル名と指定するだけでは不十分で、-p 別のプロファイル名 -no-remoteと指定する必要がありました。Firefox 67以降のバージョンではこの点が改善され、-p 別のプロファイル名と指定するだけで別プロセスのFirefoxを並行動作させられるようになりました

従来は-no-remoteオプションが必須だったため、必然的に、これらのオプションを指定したショートカットからFirefoxを多重起動しようとすると、「既存プロセスに処理が吸収されない」「しかし、新しいプロセスで使おうとしているプロファイルは、別のプロセスによって既に使用中」ということで、「Firefoxは起動していますが応答しません。新しいウィンドウを開くには既存のFirefoxをプロセスを終了させなければなりません。」というメッセージが表示されてしまうという結果になっていました。Firefox 67以降では、この制限に煩わされる事はもうありません。

-profile プロファイルのフルパス

プロファイルをフルパスで指定して起動する場合も同様に、-no-remoteオプション無しでの別プロセス起動が可能となりました。以下のように起動オプションを指定すると、それぞれのプロファイルでFirefoxのプロセスが並行して動作する状態になります。

  • "C:\Program Files\Mozilla Firefox\firefox.exe" -profile "C:\Users\username\profile1"
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -profile "C:\Users\username\profile2"

この場合、同じ起動オプションでFirefoxを多重起動すると、既に起動していてそのプロファイルを使用しているプロセスに処理が吸収されます。

また、条件を整えると、「起動オプションでプロファイル名を明示する場合」と「フルパスで明示する場合」を等価に扱うことや、あるいは、「プロファイル名を明示」「フルパスで明示」「プロファイルを明示しない」の3つを等価に扱うという事も可能になっています。

重要なのは以下の点です。

  • 当該プロファイルがプロファイルマネージャの管理下に入っている(profiles.iniにそのフォルダの情報が記載されている)。
  • 当該プロファイルのプロファイルマネージャ上の名前と、フォルダ名とが一致している。

以下は、profiles.iniを編集して上記の条件を満たすように設定したプロファイルの例です。

[Profile0]
;Name=default
Name=xxxxx.default
IsRelative=1
Path=Profiles/xxxxx.default

Firefoxのプロファイルマネージャはプロファイルを作成する際、表示用の名前の前にランダムな文字列を付与してフォルダを作成します*3この表示名が記載されているName=の行を編集し、表示名がプロファイルのフォルダ名と一致する状態にします。この状態であれば、以下の2つのコマンド列は等価に扱われるようになります。

  • "C:\Program Files\Mozilla Firefox\firefox.exe" -profile "%AppData%\Mozilla\Firefox\Profiles\xxxxx.default"
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p xxxxx.default

また、install hashとの紐付けが

[Profile0]
Name=xxxxx.default
IsRelative=1
Path=Profiles/xxxxx.default

[Install308046B0AF4A39CB]
Default=Profiles/xxxxx.default
Locked=1

のように行われていれば、以下の3パターンがすべて等価に扱われるようになります。

  • "C:\Program Files\Mozilla Firefox\firefox.exe" -profile "%AppData%\Mozilla\Firefox\Profiles\xxxxx.default"
  • "C:\Program Files\Mozilla Firefox\firefox.exe" -p xxxxx.default
  • "C:\Program Files\Mozilla Firefox\firefox.exe"

ただ、前述した通り、Firefox 67以降での新機能の恩恵を受けるためには、プロファイルをプロファイルマネージャの管理下に置く必要がある、という点に注意が必要です。「フルパスでプロファイルを明示したい場面」と「プロファイル指定無しでプロファイルを自動認識させたい場面」が重なる事はあまりありませんが、この両方のニーズを同時に満たしたいという場合*4には、見落としが生じないようにくれぐれも気をつけて下さい。

まとめ

以上、Firefox 67以降での「Firefoxのインストール先ごとのユーザープロファイルを使用する挙動」の詳細について解説しました。

Google Chromeが覇権を取った現在においては、Firefoxのニーズは一般ユーザーよりも(おそらくは検証用として)Web制作・Webアプリ開発を業としている人の方に偏っている模様です。「複数バージョンを並行して起動して検証する」という場面で特に有用なこの機能が導入されたのも、そのような背景があったからという事ではないかと考えられます。筆者ほど多くのバージョンを使い分ける事はそうそう無いと思われますが、通常リリース版・ベータ版・ESR版の3つを並行起動できるだけでも検証の負担は下がります。皆さんもこれを機に試してみてはいかがでしょうか。

また、今回の調査は現在Firefox ESR60を運用中のお客様にFirefox ESR68をご案内するにあたって、変更点の詳細を把握するために行いました。当社の法人向けFirefoxサポートでは、詳細な技術情報が提供されていない新機能の詳細の調査も有償にて承っております。「SIの業務において、お客さまの承認を得るために詳細なエビデンスの提出が求められているが、どこを対象に調査すればよいのか分からない」といった問題でお困りの方は、メールフォームよりぜひお問い合わせ下さい。

*1 正確には、Windows 2000やそれ以前のWindows NTなども含みます。

*2 Firefox 67以降のバージョンを初めて起動した時に、このような情報が追記されます。

*3 これは、ユーザープロファイルの位置を決め打ちで特定しにくいようにして、悪意の攻撃者の被害を受けにくくするための工夫です。

*4 例えば、web-ext経由でFirefoxを起動して常用しているというような場合。

タグ: Mozilla
2019-06-14

MXEを使ってUNIX系フリーソフトウェアをGNU/Linux上でWindows向けにクロスビルドする

はじめに

UNIX系のフリーソフトウェアMinGW-w64でビルドすることでWindows上で使えるものも多いですが、Windows上でのMinGW-w64およびMSYS2を使ったビルドは、UNIX系OS上でのセルフビルドと比べて非常に遅いという問題があります。こういった問題はUNIX系OS上でWindows向けにクロスビルドすることで改善することができますが、様々な環境変数やオプションを指定する必要があり、ビルド方法が煩雑になります。また、どちらでビルドするにしても、依存するライブラリについて一つ一つWindows用SDKを用意する必要があり、それらを手動で用意するのも骨が折れます。特に全ての依存ライブラリを自分でビルドしたい場合、ソースコードに手を入れなければならないことも多く、非常に手間がかかります。GNOMEプロジェクトで開発されているJHBuildというビルドシステムを使うことである程度は解決することができますが、Windowsについてはサポートが十分ではなく、素直にビルドが通らないことも多いようです。

これまでは真面目に調べたことがなかったこともあり、なかなか定番と言えるWindows向けクロスビルドシステムが存在しないなと思っていたのですが、最近になってMXE(M cross environment)というクロスビルドシステムの存在を知ったので、紹介致します。

MXEの概要

MXE(M cross environment)はUNIX系OS上からWindowsへのクロスビルドに特化したビルドシステムのようです。このようなビルド環境に特化しているため、サポートされているホストおよびターゲットであれば、ほぼノートラブルでビルドを完了できます。

ビルドシステムはGNU Makefile形式のみで記述されているためシンプルで理解しやすく、新たなパッケージを追加するのも比較的容易です。標準で収録されているソフトウェアはGTKやQt、SDLといったGUI系のものがメインで、非GUI系のものは手薄いという印象です。詳細はMXE: List of Packagesに記載されています。

ビルド環境の準備

MXEを動かすのに必要なソフトウェア一式はMXE: Requirementsに記載されています。

例えばDebianやUbuntuの場合には以下のコマンドで必要なソフトウェア一式をインストールできます。

$ sudo apt install \
    autoconf \
    automake \
    autopoint \
    bash \
    bison \
    bzip2 \
    flex \
    g++ \
    g++-multilib \
    gettext \
    git \
    gperf \
    intltool \
    libc6-dev-i386 \
    libgdk-pixbuf2.0-dev \
    libltdl-dev \
    libssl-dev \
    libtool-bin \
    libxml-parser-perl \
    lzip \
    make \
    openssl \
    p7zip-full \
    patch \
    perl \
    pkg-config \
    python \
    ruby \
    sed \
    unzip \
    wget \
    xz-utils

DebianやUbuntuではMinGW-w64もaptコマンドでインストールできますが、MXEの場合はMXEでビルドしたMinGW-w64が使用されるため、インストールする必要は無いようです。

次に、MXEをcloneします。

$ git clone https://github.com/mxe/mxe.git

cloneしたディレクトリに移動し、以下のコマンドを実行することで、要求されるソフトウェアが揃っているか否かをチェックすることができます。

$ make check-requirements

この際、トップディレクトリにビルド設定が記載された settings.mk というファイルが生成されます。
必要に応じて、ビルド前に編集しておくと良いでしょう。

# This is a template of configuration file for MXE. See
# docs/index.html for more extensive documentations.

# This variable controls the number of compilation processes
# within one package ("intra-package parallelism").
#JOBS := 

# This variable controls where intermediate files are created
# this is necessary when compiling inside a virtualbox shared
# directory. Some commands like strip fail in there with Protocol error
# default is the current directory
#MXE_TMP := /tmp

# This variable controls the targets that will build.
#MXE_TARGETS := i686-w64-mingw32.static i686-w64-mingw32.shared x86_64-w64-mingw32.static x86_64-w64-mingw32.shared

# This variable controls which plugins are in use.
# See plugins/README.md for further information.
#override MXE_PLUGIN_DIRS += plugins/apps plugins/native

# This variable controls the download mirror for SourceForge,
# when it is used. Enabling the value below means auto.
#SOURCEFORGE_MIRROR := downloads.sourceforge.net

# The three lines below makes `make` build these "local
# packages" instead of all packages.
#LOCAL_PKG_LIST := boost curl file flac lzo pthreads vorbis wxwidgets
#.DEFAULT_GOAL  := local-pkg-list
#local-pkg-list: $(LOCAL_PKG_LIST)

例えば、MXE_TARGETSを省略すると、デフォルトはi686-w64-mingw32.staticになるようですので、ターゲットをx86_64にしたい場合や、各種ライブラリを共有ライブラリとしてビルドしたい場合などは事前の設定が必要です。

例:

MXE_TARGETS := x86_64-w64-mingw32.shared

ビルド方法

ビルドは単純で、

$ make レシピ名

でビルドできます。例えばGTK3をビルドした場合は

$ make gtk3

とするだけで、依存ライブラリを含めたソースパッケージのダウンロードやビルドが自動的に実行されます。ビルドされたソフトウェアはデフォルトでは./usr/[ターゲット名]以下にインストールされるようです。

新たなソフトウェアの追加方法

MXEの各パッケージ向けMakefileはsrcディレクトリ下に[パッケージ名].mkの名前で用意されています。
拡張子が.mkのファイルは自動的に認識されるので、新たなソフトウェアは同様の方法で追加することができます。

また、前述のsetting.mkに以下のような設定があることからもわかるように

# This variable controls which plugins are in use.
# See plugins/README.md for further information.
#override MXE_PLUGIN_DIRS += plugins/apps plugins/native

MEXにはpluginという仕組みがあり、この仕組みを使って新たなパッケージを追加することもできます。プラグインとは言っても、単に.mkファイルを読み込むディレクトリを追加するだけですので、src以下の.mkファイルと同様に変数やマクロを追加(あるいは上書き)するだけです。詳細は、上記のコメントにもある通りplugins/README.mdに記載されています。

まとめ

UNIX系OS上からWindowsへのクロスビルドに特化したビルドシステムMXE(M cross environment)を紹介しました。

クリアコードが過去に関わった案件で、GTKを使用してマルチプラットフォームアプリケーションを開発されているお客様がおられましたが、ビルドシステムは独自に構築されており、そのメンテナンスに多大なコストがかかっていました。当時MXEのことを知っていれば、開発コスト低減の提案が出来ていたかもしれないな、ということが悔やまれてなりません。

2019-06-06

株式会社アカツキさまでの新人研修の一環としてOSS Gateワークショップを実施しました

結城です。

当社のOSS開発支援サービスではこれまで、SpeeeさんでのOSS開発支援やご相談窓口の設置、Supershipさまでの研修の実施などに携わって参りました。この記事ではその新たな事例として、株式会社アカツキさまで昨年および本年の新人研修の一環として開催した OSS Gate のワークショップを社内にて複数回開催させていただいた件をご紹介します。

アカツキさまへのクリアコードの関わり方

株式会社アカツキさまの事業の柱の1つはゲームの開発・運営です。お話を伺ったところ、ゲーム業界では(少なくとも、ファミコンに端を発するコンソールゲームの業界では)伝統的に、会社ごとに自社開発のライブラリやノウハウを抱え込む事が多かった事から、開発の成果を公開したり社外に開発の中心があるOSSの開発に参加したりという事はそれほど積極的には行われない傾向があるとのことでした。

しかし、現代のゲーム開発では技術が1社だけに閉じないケースが多くなっています。オンラインゲームではサーバー側の技術基盤は一般的なWebサービスと変わりませんし、クライアント側においてもUnityのスクリプトエンジンが.NET FrameworkのOSS実装のMonoであったりします。また、ゲーム本体から周囲に目を向ければ、そもそも開発に使用するGitやVisualStudio CodeなどのツールもOSSです。このように、サービス提供も開発も今やOSS無しではままならないというのが実情です。こういった背景があり、アカツキさまでは「会社としてOSS活動を推進していきたい」という意気が高まっていたそうです。

これを踏まえて、アカツキさまの技術アドバイザーSpeeeさまの技術顧問を兼任されている井原さんから当社をご紹介頂き、アカツキさまのOSS活動推進の取り組みをお手伝いさせて頂くこととなりました。その際、具体的な取り組み方について相談した結果、まだOSS活動に関わったことがない人が多い・(今後の進め方を考えるために)当社が現状を把握したいという理由から、まずは当社メンバーが案内役を務める形で OSS Gate ワークショップをアカツキさま社内で開催することとしました。

OSS Gate ワークショップ in アカツキ

OSS Gate ワークショップは、参加者を「まだOSS開発に関わった事が無い人=ビギナー」と「OSS開発に関わった経験がある人=サポーター」に分けて、ビギナーが主体的に作業を進めるのをサポーターが手助けする*1という形で、バグ報告やパッチの提供などの「フィードバック」をする体験をして頂くイベントです。今回は、ビギナーとしては主に新入社員の方や中途採用されて日が浅い方に多くご参加頂く結果となりました。また、通常の公開で行う OSS Gate ワークショップではサポーターは広くボランティアを募っていますが、今回はサポーターも皆アカツキさま社内の方に務めて頂きたいという事で、こちらも社内で希望者を募ったり、アカツキ内でこの取り組みの主担当をされているシニアエンジニアの島村さんから指名して頂いたりしました。これは、サポートする側を経験して頂く事により、普段から業務の中で他の方のOSS開発への参加を手助けして頂きやすくなればという目論見があったためです。

開催形態は東京で開催している OSS Gate ワークショップの形態を踏襲し、1人のサポーターが1~2人のビギナーと組む形としました*2。参加希望者のスケジュールが合う日がバラバラだったため複数の日に分けて開催することとし、2018年には4回、2019年には3回に分けて実施しました。

ワークショップは通常は1日がかりで行いますが、今回はアカツキさまの業務の都合もあり、内容を一部省略して所要時間を2/3~半分程度に短縮しての実施としました*3

(写真:2019年開催分の様子)

各回の参加者アンケートは OSS Gate ワークショップのリポジトリで公開されており、以下から閲覧可能です。

OSS Gate ワークショップはフィードバックの過程を体験して頂くという趣旨のイベントなので、バグ報告やパッチ提出などの形に残る結果を出すことを必須には設定していません。そのため、通常の OSS Gate ワークショップはフィードバックに至る手前で時間切れになる方も多いです*4。ただ、アカツキさまでの開催分については研修で前提知識が共有されている部分が多いためか躓きはあまり発生せず、ほとんどの方が時間内に実際にフィードバックを行う段階まで到達されていました。

筆者が印象的だった出来事としては、ビギナーの方が選択を検討されていたソフトウェアが実はOSSではなかった、という事例がありました。ゲーム業界ということでUnityを使われている方が多く、その方は「ユニティちゃんライセンス」が設定されたプロジェクト(unity3d-jp/unitychan-crsなど)へのフィードバックを検討されていたのですが、調べてみると、当該ライセンスはOSIが認定済みのOSSライセンス一覧には掲載されていませんでした*5。この事例のように、GitHubにリポジトリがある・ソースコードが閲覧可能な状態になっているからといってOSSであるとは限らない、という点は意外と見落としてしまいがちなので、皆さんもくれぐれもご注意下さい*6

なお、この一連のワークショップが契機となってか、後に参加者の方が新たにOSSを公開されたという事を後からお知らせ頂きました*7。OSS Gate ワークショップではフィードバックをする際の注意点として「作者(プロジェクト運営者)にとって分かりやすくなるように報告内容を整理する」という事を度々伝えていますが、自分自身が作者としてOSSを公開する側になると、実際にフィードバックを受ける際にどのようなフィードバックであれば助かるかという事を、より実感を持って考えられるようになるはずです。得るものは多いと思われますので、開発したソフトウェアをOSSとして公開する事にも、皆さんには是非チャレンジして頂きたいです。

継続的なOSS活動の推進のためのふりかえり

アカツキさま社内での OSS Gate ワークショップ開催は、ゴールではなく最初の一歩という位置付けです。そのため、毎回のワークショップ終了後にはアンケートの回答を見ながら参加者全員で「どうすれば、社内にOSS活動が根付くか?」という事を考えるふりかえりの時間を設けました。

ワークショップ後も継続してフィードバックしていく事が根付くかどうかが課題であるという点は、公開で開催されている OSS Gate ワークショップと共通している様子でした。アカツキさまのケースでは特に、「業務と並行してフィードバックも行う」という事を全体でどう習慣化していくかが課題という事になります。この点について、各回のアンケートの回答からは、現在は「普段の業務」と「OSS活動」を全く別の物として捉えている方が多いようで、「普段の業務をしていると、OSS活動をする時間がない」と認識されている様子がうかがえました。

業務上使用しているツールやライブラリの不具合を見つけた場合、仮にそれが自社開発の物であれば、不具合を伝えて修正してもらうという事は、業務の中の出来事として受け入れやすいでしょう。その際にはもちろん、修正する側にとってわかりやすい形の障害報告にするという事も求められるはずです。業務で使用するOSSへのフィードバックも、報告先が公開のイシュートラッカーであったり、報告に使う言語が英語であったり*8という差異はあるものの、基本的にはそれと同じ事と言えます。よって、心理的な障壁をどのようにして取り除くか、いかにして「業務の活動をしていたら、それが自然とOSS活動になっていた」と言える状況を作るか、という事が重要なのではないかと思われます。

ただ、業務での開発では「ライブラリやツールのバージョンは開発時点の物で固定し、最新版へは更新しない」といった事も行われがちです。その場合、フィードバックの結果が業務に反映されることが無いという事になってしまうので、開発元へのフィードバックに時間を使う事に対して「業務と無関係な事をしている」感覚が強くなってしまう、という側面はありそうです。この種の問題については個人でどうにもなりませんので、むしろ、古いバージョンのソフトウェアを使い続ける事にはセキュリティなどの面でリスクがあるという認識を全員で持って、適宜ソフトウェアのバージョンを上げていく健全な開発・メンテナンスのスタイルを取り入れていくという、普段の開発そのものの見直しも必要になってくるでしょう。

こういった事を全体で一気に推し進めるのは困難が伴います。アカツキさまでは元々、日常的にフィードバックをされている方の周囲ではスポット的にそのような動きが見られるとのことですので、全体を一気に改革するという事には拘らず、周囲の人に影響を与えるリーダーとなる人を増やした上で部分部分のできる所から進めていく、というのが無理のない進め方なのかもしれません。

また、この取り組み全体を担当されているシニアエンジニアの島村さんと一緒に行った、全体を通してのふりかえりの中では、OSSへのフィードバックで困った人が表れた時の気軽な相談先として当社をお使い頂く、というような方向でのOSS推進もご検討頂きました。

まとめ

以上、アカツキさまでのOSS推進の取り組みの一環として実施した OSS Gate ワークショップの様子をご紹介しました。

当社では「自社内にOSS開発者を育てたい」「OSSへのコントリビュートを行いたい」といった企業さまのご依頼を受けて、人材育成や社内文化の改善といった観点からご協力させて頂くというOSS開発支援サービスを行っています。今回のアカツキさまでの事例のように、社内事情に合わせて規模や内容をカスタマイズしての OSS Gate ワークショップ開催のお手伝いも承っております。社内で旗振り役を務められる人が少ないためにOSS活動をうまく推進できていない、などのお悩みをお持ちの方がいらっしゃいましたら、是非メールフォームよりお気軽にお問い合わせ下さい。

なお、近い日程では2019年6月8日にOSS Gate 東京ワークショップが開催される予定です。公開のOSS Gateワークショップはサポーター側が不足しがちなため、ビギナー側での参加は枠がすぐ一杯になってキャンセル待ちになりやすいのですが、「バグ報告をした事がある」という方はサポーターとして登録して頂ければ、多くの場合はそのまま参加できます。会社としてOSS活動を奨励していきたいという方は、実際にワークショップに参加して頂くと雰囲気や要領を参考にして頂けると思いますので、是非ご検討下さい。

*1 詰まった時にヒントを出す、迷ったときにアドバイスするなど。

*2 東京開催分は、現在は基本的に1人のビギナーに1人以上のサポーターが付く形態とし、サポーターの人数以上のビギナーを集めない方針を取っています。アカツキさま社内での開催に関してはビギナー参加者を可能な限り多く受け入れる必要があったため、進行役・サポートメンターを加えればマンツーマンに相当する人数比は維持できそうという事から、この人数に設定しました。

*3 過去には、PHPカンファレンスの中で一室を借りて実施した際にもこの形態を取りました。

*4 Gitの使い方に手間取ったり、課題選びに悩んだり、選んだ課題の規模が大きすぎて準備に時間がかかったり、という例が多いようです。

*5 OSIでは、オープンソースの定義に合致していて、且つOSIで認定されているライセンスに基づくソフトウェアのみをOSSと呼ぶ事を推奨しています。また、よくある質問の回答として、オープンソースの定義に合致していても一覧に掲載されていない物をOSSライセンスと称する事は混乱を招くため、(承認され一覧に掲載されるまでは)「独自のOSSライセンス」を無闇に策定・自称しない事が求められています。なお、筆者がユニティちゃんライセンスの文面を確認した限りでは、営利目的での利用の禁止などの条件がオープンソースの定義に合致しないようでした。

*6 OSSでなくとも、ライセンスの条件に従って利用する限りにおいては何ら問題ありません。また、OSSライセンスでないライセンスを設定する事もここでは否定していません。ただ、OSSライセンス同士であっても条件が互いに矛盾するために成果物を組み合わせられない場合はあり、OSSライセンスとOSSでないライセンスとの組み合わせでは余計にそのような状況が発生しやすい、という事は言えます。

*7 s-luna/AndroidReplayRecorder

*8 作者が日本語話者のOSSでは、日本語でフィードバックするという事もありますが、多くの場合は英語が使われています。

2019-05-29

最新記事
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|