UNIX系のフリーソフトウェアはMinGW-w64でビルドすることでWindows上で使えるものも多いですが、Windows上でのMinGW-w64およびMSYS2を使ったビルドは、UNIX系OS上でのセルフビルドと比べて非常に遅いという問題があります。こういった問題はUNIX系OS上でWindows向けにクロスビルドすることで改善することができますが、様々な環境変数やオプションを指定する必要があり、ビルド方法が煩雑になります。また、どちらでビルドするにしても、依存するライブラリについて一つ一つWindows用SDKを用意する必要があり、それらを手動で用意するのも骨が折れます。特に全ての依存ライブラリを自分でビルドしたい場合、ソースコードに手を入れなければならないことも多く、非常に手間がかかります。GNOMEプロジェクトで開発されているJHBuildというビルドシステムを使うことである程度は解決することができますが、Windowsについてはサポートが十分ではなく、素直にビルドが通らないことも多いようです。
これまでは真面目に調べたことがなかったこともあり、なかなか定番と言えるWindows向けクロスビルドシステムが存在しないなと思っていたのですが、最近になってMXE(M cross environment)というクロスビルドシステムの存在を知ったので、紹介致します。
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のことを知っていれば、開発コスト低減の提案が出来ていたかもしれないな、ということが悔やまれてなりません。
Firefox 67の新機能の1つに、インストール先ごとにプロファイルが分けられるようになったという物があります。
この記事では、Firefoxのユーザープロファイルの仕組みの歴史的な経緯や、プロファイル切り替えの仕組み自体がどのように使われてきたかという点を踏まえながら、Firefox 67での新機能の性質を解説します。
Firefoxのユーザープロファイルの仕組みは、元を辿ると、その前身となったNetscape Communicatorのユーザープロファイルの仕組みに行き着きます。
Netscape Communicatorが現役だった頃に広く使われていたWindows 95やWindows 98は、原則としてユーザーは1人だけであるという前提で設計されていたため、複数人で同じPCを共用する場合にユーザーを使い分けるという事ができませんでした。そのためNetscape Communicator独自の概念として「使用者ごとにユーザープロファイルを作り分けて、設定値やブックマークなどはその中で管理する」という仕組みが用意されました。
その一方で、Windows XP以降のバージョン*1ではOS自体が複数ユーザーを想定した設計になっています。アプリケーション側で個別にユーザープロファイルを管理する必要は無く、アプリケーションの設定を使用者ごとに使い分けたい場合、単純にWindowsのユーザーを使い分ければよいという事になっています。
以上のような歴史的な経緯があり、Firefoxのユーザープロファイルは「Windowsのユーザープロファイルごとに、複数のFirefoxのプロファイルが存在しうる」という少々複雑な状況となっています。
実際には、Windowsのユーザーを使い分ければよい現状においては、使用者ごとにFirefoxのプロファイルを使い分けないといけないという状況はまず発生しません。よって、Firefoxのユーザープロファイルは今では1人のユーザーが、「仕事用」「開発用」「趣味用」といった何らかの用途ごとに使い分けるという用途が主流になっています。
ただ、一般的なユーザーが普段使いにおいて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などの認証情報は用途ごとに切り替えたい」という、実際の使用局面でよく見られるニーズに応えるものとなっています。
ユーザープロファイルの使い分けよりもはるかに手軽に使えるため、これらの機能で充分に用を果たせる場面では、ユーザープロファイルの使い分けのニーズはほぼ無くなったと言ってよいでしょう。
以上のような経緯から、現在の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」と「特定のユーザープロファイル」とはどのように紐付けられているのでしょうか。鍵になるのは、インストール先のパスに基づく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を別々の位置にインストールする必要があります。)
上記の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」となるため、標準のブラウザや関連付けの対象を選択する場面で同じ名前の項目がいくつも並んでしまうという事が起こってしまうのです。
現在の所、この問題を解決するには手動でのレジストリの編集が必要です。この一覧に表示されるアプリケーション名は 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 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
オプション無しの動作と似た結果になります。
別のプロファイルを指定して別のプロセスを並行動作させたい場合、従来は-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を起動して常用しているというような場合。
Apache Arrowの開発に参加している代表取締役の須藤です。
もう2ヶ月前の話なのですが、2019年のGoogle Open Source Peer Bonusの1人に選ばれました。選ばれるまでこんな取り組みがあることを知らなかったのですが、2011年からやっているそうです。オープンソースの開発に関わっている人を支援する取り組みだそうです。賞金(?)として250ドルもらいました。ありがとうございます。
Apache Arrowの開発をがんばっているということで選んでもらいました。現時点で私は2番目にコミット数が多いのでそのあたりを評価してくれたのかもしれません。ちなみに、1番コミット数が多いWesさんはpandasの開発で選ばれていました。
私の自由なソフトウェアの開発を支援したいけどどう支援したらよいかわからないという方はご相談ください。
※注:この記事の対象読者は、「OSSを使用していてトラブルに遭遇しているか、改善の提案があり、その情報を開発元に伝えたいが、どこで伝えればよいかわからない」という人です。「どういう体裁で報告すればよいか分からない」「何を報告すればよいか分からない」という人向けの話はまた日を改めて書くつもりです。
結城です。
OSS Gateワークショップで、初めてフィードバックをしようとしているビギナー参加者のサポートをしていると、ビギナー参加者から以下のような質問を受ける事があります。
これらの点に対する筆者の回答は、端的には以下のようになります。
奇しくも最近、これらの事を考える上で非常に興味深い事例に出会いました。以下、それを題材として上記の点をどのように判断しているのかを語ってみます。
当社の法人向けのThunderbirdサポートにおいて、数ヶ月前から複数のお客さまより「メール作成時に日本語入力で漢字への変換ができなくなる」という現象のお問い合わせを頂くという事がありました。
お問い合わせの中にはMozillaZineフォーラムに同様の事例の報告がある旨をお書き添え頂いた物もあり、参照してみると、スレッドの大まかな流れは以下のようになっていました。
当社の検証環境でも、条件が整うと確かに現象が再現するという事を確認できました。そこで、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、やる気次第で自分から参入できます。
こういったモヤモヤを感じた時に、「でも、手を出せないんだからしょうがない」と諦めないで根本的解決できる可能性が開かれているのが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 当社の法人向けサポートサービスは、お客様の問題(個別の問題)について原因や回避方法を調査してその解決を図ると同時に、その問題がソフトウェアの問題であった場合はソフトウェアの品質向上のためアップストリームへのフィードバックも行う事を心がけています。
※注:この記事の対象読者は、「OSSを使用していてトラブルに遭遇しているか、改善の提案があり、その情報を開発元のイシュートラッカーに伝えようとしているが、どんな内容を書けばよいかわからない」という人です。そもそも「どこに報告すればよいかわからない」「イシュートラッカーに書き込んでいいかどうか不安がある」という方は、1つ前の記事をご参照下さい。
結城です。
1つ前の記事では、フォーラムとイシュートラッカーのどちらに書き込めばよいかわからない場合の考え方について詳しく語りました。その際、両者の目的の違いを以下のようにまとめました。
この記事ではその続編として、イシュートラッカーの目的から導かれる「適切な、書くべき報告の内容」を語ってみます。
フォーラムとイシュートラッカーの目的の違いは、「投稿する内容をどうまとめればよいのか」という事を考える時の指針にもなります。「ソフトウェアの問題の解決」を目的とするイシュートラッカーに報告する内容は、その目的に沿って、「ソフトウェアの開発に関わる人達が、このソフトウェアの問題を解決するには、どのような情報が必要か?」という視点で整理する事になります。
例えば、以下の3項目は典型的な「書くべき内容」です。
その問題のせいで自分がいかに困っているか? という訴えは報告のメインの内容とはなり得ません。プロジェクト全体の中でその問題の重要度の高さを認識してもらうための材料として、問題の影響度・深刻さの説明としてそれらの訴えを盛り込む場合はありますが、そのような訴え自体が問題の原因究明や修正箇所の特定に役立つという事は、基本的には無いからです。
しかし、いざ報告しようとしても、
という心配から報告をためらう、という事例はワークショップの中でもよくあります。筆者はそのような場合には、「不安を感じるくらいなら、自分が思う内容・表現のままでそのプロジェクトに報告してしまってよい」とアドバイスする事が多いです。
既知の報告がないか全く調べていない、というのはさすがにまずいですが、自分の思いつく表現で検索して報告が見つからないなら、その表現で報告して大抵は問題ありません。なぜなら、仮にその後既知の他の報告と重複していると分かって、そちらに誘導された上でクローズされたとしても、その報告内容自体が、同じ探し方をする人のための今後の誘導になるからです。
適切な報告先プロジェクトかどうか分からない、という場合も同様です。その問題が根本的には別のソフトウェアの問題だったと後から分かっても、同様の現象に遭遇した人のための誘導になるので、報告は無駄にはなりません。例えば1つ前の記事で紹介した事例では、今後同様の現象に見舞われて検索して辿り着いた人は、今後はMicrosoft IMEの動向に注意するとよい、という情報を得られる事になります。
また、根本的な原因については既に報告があったとしても、その報告で触れられている以外の現象の情報があると、それは問題の影響度合いを示す情報になります。当初の報告では些細な問題だから後回しにしようと判断されていた物が、実はユーザーレベルで大きな影響を受ける物だったと分かって、対応の重要度・緊急度が引き上げられるという事は度々あります。
明らかな不具合というよりは「こうなっているとより良い」という提案の性質が強い報告の場合に多いのですが、「それは対応しない」「やらない」と判断され却下される場合もあります。そのような場合も、「無駄だった」「失敗した」という考え方をする必要はありません。というのも、「ある提案が却下された」という事そのものにも意義があるからです。
OSSのプロジェクトのスコープ*1は、必ずしもすべて明確化されているとは限りません。ある人にとっては「当然あるべき」と思える機能が無かったり、逆に、「無駄にしか思えない」という機能があったり、特に、それについて何の説明も無いという事はざらにあります。大規模なプロジェクトでは、すでに参加している人の間ですら解釈が別れていたりもします。
しかし、例えスコープが明文化されていなくても、一貫性を持った数々の判断の結果、その輪郭は段々と浮かび上がってきます。新たな判断の事例が1つ増えるという事は、不明瞭だった基準がより明確化されたという事になり、後から来た人にとって有用な情報となります。また、判断と共にその根拠が示されていれば、後になって状況が変わり根拠が薄れた時などに、それを理由として再考を求める事もできます。
そのような意義ある判断を引き出すためにも、議論は「自分の意見を押し通すため」ではなく「プロジェクトの目的をより良く達成するため」という点を念頭に置いて、「相手(敵) v.s. 自分」ではなく「問題 v.s. プロジェクト」という方向で行いましょう。反論も、主張の材料を補ったり、説明しきれていなかった理由を追加で説明したりと、意味のある反論をする事が肝要です。感情的に同じフレーズを繰り返すだけや、明確な根拠無しに強弁するだけのような不誠実な態度、他の参加者の共感を得られないゴリ押しは、百害あって一利無しです。
ただし、実際に手を動かす人が足りないから労力的に対応できないという理由で却下される場合は、より深く関わるチャンスです。自分で実装してパッチ(プルリクエスト)を提出し、その後もメンテナンスを引き受け続ければ、あなたも立派に開発者の仲間入りという訳です。
といった点で悩んで報告をためらう、というケースもあります。筆者はこのような場合、「対案は無くてもいいから、まず報告してみよう」とアドバイスします。
もちろん、コードのレベルで修正の仕方まではっきり分かっているのなら、パッチやプルリクエストの形でフィードバックできるに越した事はないです。しかし、そうできないならフィードバックしない方がよい、という事はありません。
むしろ、自分の考えつく解決策が最良であるとは必ずしも限りません。詳しい事情が分かっていない段階で自分の思い込みだけで独りよがりに実装を作り込んでしまうと、その労力がまるっきり無駄になるという事もあり得ます。例えば、ある機能の不具合を見つけて、その問題を解消するための複雑な変更を持ち込んだが、単にその機能全体を既存の別ライブラリで置き換えれば済む事だった、というような事はよくあります。筆者も、過去に強引な実装のパッチを代理で投稿してもらった事がありましたが、実装の筋が悪すぎたためか、それ以上話が進む事はありませんでした。
イシュートラッカーは「問題の解決」に取り組むための場であって、「特定の解決策の実現」に取り組む場ではありません。解決策は関わる人みんなで考えてよく、一人で抱え込む必要はないのです。よく「文句を言うなら対案を示すべき」という言い方がされますが、だからといって「対案が無いなら文句を言ってはならない」は真ではありません。問題解決に取り組む1つのチームの一員として、対案を考える事も含めて皆で取り組む、という姿勢・考え方をするのがポイントです。
真摯に議論しようという話とも共通しますが、「問題を解決する開発者達 v.s. 外部から善意で協力しているただのユーザーの自分」という壁を自ら作る事は避けた方がよいです。対等な関係ではないという事を過剰に意識してしまうと、実際以上に大きな上下関係を自分の中に作り上げてしまい、コミュニケーションの妨げになります。
1つ前の記事ではOSSに新たに関わる人を新入社員に例えましたが、そう考えれば、なぜ自分とプロジェクトの間に過度に壁を作るべきでないのかが分かるのではないでしょうか。新メンバーがお客様気分で上げ膳据え膳に期待してふんぞり返るのはおかしいですし、かといってへりくだりすぎるのもおかしいですよね。
無論、雇用されフルタイムで開発に従事している人と、外部から余力の範囲で関わっている人の間では、立場も権限も異なります。しかし、そのプロジェクトの目的、あるいは報告した1つの問題の解決に向けて一緒に取り組む仲間という点では差は無いはずですから、お互いに敬意を持って接する事が大事です。
特に、「自分は問題で損をした被害者なんだ。その被害者自身がわざわざ協力してやってるんだ。だからお膳立てはあいつらの方で整えてくれて然るべき」というような捉え方は、問題の解決を遠のけさせこそすれ、近づけさせは決してしません。このような意識を強く持ってしまうと、相手の無理解を責めたり相手をやり込めたりする事にばかり意識が向いてしまい、ひいては特定個人に対する罵倒や中傷にまでエスカレートし得ます*2。
以上、OSSにフィードバックする事に不慣れな場合に悩みがち・判断に迷いがちと思われる点について、イシュートラッカーの目的から導かれる「適切な考え方」を、筆者の感覚から語ってみました。
表現を変えながら繰り返し何度か述べていますが、OSS開発に関わる際は基本的に「問題 v.s. それに立ち向かうプロジェクト参加者達(そして、その一員としての新人の自分)」という構図で考え取り組む事が大事だというのが、筆者の考えです。かつては思ったように成果を出せなかった自分も、そのように考えられるようになって以降は、より有用な報告ができ、提出したパッチやプルリクエストを取り込んでもらえる機会も増えたように思います。まだOSSの開発への参加に不慣れで、報告がうまくいかなくて悩んでいるという方は、この記事で述べた点を意識してみてはいかがでしょうか?
また、この記事で述べた事は実際にはOSSに特有の話ではなく、一般的に企業内でバグ票をやり取りするような場合にも共通して言える事です。1つ前の記事ではOSSのイシュートラッカーを出入り自由の社屋や工場に例えましたが、OSS開発の場で広く共有されているノウハウの中には、普通に仕事の上で有用な物も多く含まれています。特に、OSS開発では「多くの人を雇って人海戦術で乗り切る」というような力業での解決が難しいため、いかに少ないコストで最大の効用を得るかという点で工夫がなされている事も多いです。当社のOSS開発支援サービスでは、OSS開発に参加していきたいという企業さまのお手伝いだけでなく、OSSコミュニティでの開発ノウハウを企業内での開発に活かすお手伝いも承っています。そういった事に関心をお持ちの担当者さまがいらっしゃいましたら、ぜひお問い合わせフォームよりご連絡下さい。
CSSにはime-mode
というプロパティがあり、これによりinput要素やtext要素でインプットメソッドの入力モードを制御することができます。この仕様は廃止されることが決まっているため積極的に利用すべきものではありませんが、一方で代替となる仕様や実装が無いこともまた事実です。日本の業務システムでは、入力業務効率化の必要性から、今なおこの機能を利用している事例も多いようです。
この仕様はInternet Explorer由来のものですが、Firefoxも同仕様をサポートしています。ただし、GNU/Linux版ではサポートされている機能が限定的で、active
やinactive
はサポートされていません。これは、GNU/Linux版Firefoxがプラットフォーム層として利用しているGTK側の制約に依るものです。
弊社でも「GNU/Linux版Firefoxでime-mode
を使用することはできないか?」というお問い合わせを受けたことが過去に何度かあります。
最近、とあるお客様から「どうしてもこの機能をGNU/Linux版Firefoxで実現したい」という強いご要望があったため、新たにime-mode-weというアドオンを作成してお応えしました。
同アドオンは、今のところ多言語入力フレームワークとしてIBusを、入力エンジンとしてAnthy、KKC、Mozc、SKKのみをサポートしています。
アドオン自体は、通常のアドオンと同様に、同ページから「Firefoxへ追加」ボタンを押すだけでインストールすることができます。ただし、このアドオンはシステムネイティブのコマンドを呼び出す形で実装されているため、このネイティブコマンドについても別途インストールする必要があります。同ページにも記載していますが、以下の手順でネイティブコマンドをインストールして下さい
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だけでなく、初期状態をカタカナや半角カタカナなどに切り替えるといった機能も実現できるかと思います。
もしこういったカスタマイズのご要望がある場合は、ぜひ弊社お問い合わせフォームよりご連絡下さい。