遥かへのスピードランナー

シリコンバレーでAndroidアプリの開発してます。コンピュータービジョン・3D・アルゴリズム界隈にもたまに出現します。

Firefoxの内部動作を理解する方法2-WindowsでFirefoxをビルドしてみる

前回Firefoxの内部動作を理解する方法1-デバッグログを出力するのエントリーでNSPRモジュールを利用したデバッグログ出力方法を紹介しました。が、これだけでもまだ不満がある方もいると思います。
たとえばNSPRモジュールは、日時やメッセージ出力元のモジュール名などを表示してくれないので、実際デバッグログとソースコードを照らし合わせるのも結構大変だったりします。
もっと細かいログが見たい、とか、カスタマイズして動作を確認してみたい、という人にはFirefoxを自分でビルドしてみるのがお勧めです。
Mozilla各プロダクトのビルド手順は、MozillaBuild Documentationでもまとめられてはいるんですが、ちょっと分かりづらかったり、リンク切れがあったりするので自分なりにまとめてみました。

ビルド対象

準備するもの

以下のツール郡が必須になります。
VisualStudioのバージョンはFirefoxのバージョンに応じて何種類か選択肢があるのでhttp://developer.mozilla.org/ja/Windows_Build_Prerequisitesで確認しましょう。
Firefox2.0.0.9にはVisualStudio6.0が最適みたいです。

  • VisualStudio 6.0
  • VisualStudio 6.0SP5
  • Visual C++ 6.0 Processor Pack

VS持ってない人は買いましょう。SP6ではビルドできないみたいです。
また、Processor Packは、microfostの日本語のページではSP4用のものしかありませんので、SP5用にはhttp://msdn.microsoft.com/en-us/vs2005/aa718349.aspxからダウンロードします。
ちなみに、VSのインストールが必須といっても、別にVSのGUIを使ってFirefoxをビルドするわけではなく、あくまでコマンドラインでのビルドなので注意。

なぜかVista SDKが必須。
http://www.microsoft.com/downloads/details.aspx?familyid=4377F86D-C913-4B5C-B87E-EF72E5B4E065&displaylang=en
からダウンロードしましょう。

  • MozillaBuild

http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-1.3.exe
からダウンロードして導入。

ソースコードの入手・展開

ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/
あたりから欲しいバージョンのソースコードを入手。
今回は2.0.0.9をターゲットにしているので、
ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.9/source/firefox-2.0.0.9-source.tar.bz2
からダウンロードして展開します。
注意しておきたいのは、

  • ソースを展開する場所は「Documents and Settings」など空白の入ったパス以下を避ける
  • 展開後のフォルダ名はmozillaから変更しない

この2点です。両方ともmakeが失敗する可能性があります。
今回はC:\workspace\mozillaに展開されたものとして話を進めます。

設定ファイルの編集

ソースを展開したC:\workspace\mozillaフォルダの直下に.mozconfigファイルを作ります。
[C:\workspace\mozilla\.mozconfig]

. $topsrcdir/browser/config/mozconfig
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/ff-opt
ac_add_options --disable-tests

"mk_add_options MOZ_OBJDIR="は、make後のオブジェクトファイルの置き場を指定するオプションです。
これを指定しないと再ビルドするときmake cleanしなければいけないなど面倒なので、指定しておきます。
この設定では、C:\workspace\mozilla\ff-opt以下にオブジェクトファイルが作られ、再ビルドするときはMOZ_OBJDIRの指定を別フォルダに変更してやるか、ff-optフォルダを削除すればビルドすることができます。
"ac_add_options --disable-tests"はテストプログラムのビルドを省略するオプションです。自分がビルドしたときに、テスト系の一部プログラムがコンパイルできずにビルドが止まっていたのでこちらのオプションを指定しています。
他に設定できるオプションなど、より詳しくはhttp://developer.mozilla.org/ja/Configuring_Build_Optionsを参照。
ちなみにデバッグ用のビルドオプションである

  • ac_add_options --disable-optimize
  • ac_add_options --enable-debug

も試してみましたが、デバッグ出力が特に多いわけではなく、ビルドに時間がかかり動作も不安定になるのでお勧めはしません。。

ビルド

C:\mozilla-build\start-msvc6.bat
を叩いて、MSYSコマンドプロンプトを起動する。無事起動すると入力待ちになるので、

$ cd /c/workspace/mozilla

とソースを展開した場所まで移動して

$ make -f client.mk build

としてmakeを実行。環境にもよりますが、大体1時間程度でビルドは終わると思います。
エラーが表示されなければ無事ビルド完了で、C:\workspace\mozilla\ff-opt\dist\bin\firefox.exeが出来ているはずです。

起動

C:\workspace\mozilla\ff-opt\dist\bin\firefox.exeをクリックして、profileの選択画面が表示されれば成功です。(自分の環境の場合、1度クリックしただけは反応しない場合がありましたが2度目のクリックで起動しました。)テスト用のprofileかなんかを適当に作って起動しちゃいましょう。
ところどころにBon Echoと書いてありますが間違いなくFirefoxです。(Bon EchoFirefoxの開発コードネーム)

まとめ

VisualStudioさえあれば、結構簡単にビルドできます。
ちょこっと自分で直したりしても意外にスムーズに動くので、お勧め!

Firefoxの内部動作を理解する方法1-デバッグログを出力する

FireMobileSimulatorも含めたFirefoxアドオンの今後の開発の可能性を探る為に、Firefoxの内部動作をもう少し詳しく知りたいなあと思ってたんですが、ソースを読んでみても、細かいところは分かっても、全体を通してどう動いているかがどうにも分かりません。。
しかし、Firefoxを含む各種MozillaプロダクトにはNSPRという便利なモジュールが組み込まれていて、再ビルドなどを行うことなしにデバッグログをファイルに出力させることができるということを最近知りました。
このログを追えば、そのプロダクトのだいたいの動きを知ることができます。

NSPRモジュールのログ出力方法

NSPRモジュールの使い方は簡単で、Windowsの環境変数でNSPR_LOG_MODULESとNSPR_LOG_FILEを指定してFirefoxを起動するだけです。

それぞれの環境変数の説明は以下の通り。

NSPR_LOG_MODULES

「モジュール名:ログレベル」をカンマ区切りで指定します。
すべてを網羅できているか保証はないのですが、ここにモジュール名とソースファイル名の対応付けがあります。
ログレベルは0から5までの数値を指定します。それぞれの数値の意味は以下の通り。

Level Meaning
0 no logging output
1 informational messages
2 error messages
3 warning messages
4 debug messages
5 all messages

たとえば、NSPR_LOG_MODULES=ALL:5と指定するとすべてのモジュールのすべてのメッセージがログファイルに出力されますし、NSPR_LOG_MODULES=nsHttp:1と指定すると、HTTPリクエスト・レスポンスに関係するInformationログが出力されます。

NSPR_LOG_FILE

ログファイル名を指定します。相対パスでも絶対パスでもOKです。

実際にやってみる

上記をふまえて、以下のようなFirefox起動batファイルを用意しておくと便利です。
[debugrun-firefox.bat]

set NSPR_LOG_MODULES=ALL:5
set NSPR_LOG_FILE=firefox.log
c:
cd "\logs"
"C:\workspace\mozilla\ff-opt\dist\bin\firefox.exe"

これで起動するとC:\logs以下に以下のようなログファイルが出力されます。
[firefox.logより抜粋]

0[af2800]: nsHttpHandler::NewURI
0[af2800]: Creating nsStandardURL @365cf38
0[af2800]: nsStandardURL::SetSpec [spec=http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/]
0[af2800]:  spec      = http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/
0[af2800]:  port      = -1
0[af2800]:  scheme    = (0,4)
0[af2800]:  authority = (7,15)
0[af2800]:  username  = (7,-1)
0[af2800]:  password  = (7,-1)
0[af2800]:  hostname  = (7,15)
0[af2800]:  path      = (22,35)
0[af2800]:  filepath  = (22,35)
0[af2800]:  directory = (22,35)
0[af2800]:  basename  = (57,0)
0[af2800]:  extension = (57,-1)
0[af2800]:  param     = (22,-1)
0[af2800]:  query     = (22,-1)
0[af2800]:  ref       = (22,-1)
0[af2800]: Destroying nsStandardURL @365cf38
0[af2800]: nsHttpHandler::NewURI
0[af2800]: Creating nsStandardURL @365cf38
0[af2800]: nsStandardURL::SetSpec [spec=http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/]
0[af2800]:  spec      = http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/
0[af2800]:  port      = -1
0[af2800]:  scheme    = (0,4)
0[af2800]:  authority = (7,15)
0[af2800]:  username  = (7,-1)
0[af2800]:  password  = (7,-1)
0[af2800]:  hostname  = (7,15)
0[af2800]:  path      = (22,35)
0[af2800]:  filepath  = (22,35)
0[af2800]:  directory = (22,35)
0[af2800]:  basename  = (57,0)
0[af2800]:  extension = (57,-1)
0[af2800]:  param     = (22,-1)
0[af2800]:  query     = (22,-1)
0[af2800]:  ref       = (22,-1)
0[af2800]: nsDocShell[362cfa0]: loading http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/ with flags 0x00000000
0[af2800]: DOCSHELL 362cfa0 InternalLoad http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/
0[af2800]: Content Policy: ShouldLoad: <http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/> <Ref:None> result=ACCEPT
0[af2800]: DocLoader:362cfa0: Stop() called
0[af2800]: nsHttpHandler::NewChannel
0[af2800]: nsHttpHandler::NewProxiedChannel [proxyInfo=0]
0[af2800]: Creating nsHttpChannel @36ee008
0[af2800]: nsHttpChannel::Init [this=36ee008]
0[af2800]: host=www.mozilla.org port=-1
0[af2800]: uri=http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/
0[af2800]: Creating nsHttpConnectionInfo @365d120
0[af2800]: nsHttpHandler::AddStandardRequestHeaders
0[af2800]: nsURILoader::OpenURI for http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/
0[af2800]: [0x36ee768] nsDocumentOpenInfo::Open
0[af2800]: nsHttpChannel::AsyncOpen [this=36ee008]
0[af2800]: ===== COOKIE SENT =====
0[af2800]: request URL: http://www.mozilla.org/projects/firefox/2.0.0.9/whatsnew/

どうでしょう?HTTPリクエストがどうできて、どう送られるかというのがソースの動きとしてよくわかります。
ただ、中にはこれでも満足できない、もっと深いところまで知りたい、という人もいるかも知れません。
そういう場合は、自分でビルドしてみることをおすすめします。
ビルド方法についてはまた別のエントリで。

FireMobileSimulator0.1.4リリース&CodeReposにコミットしました

FireMobileSimulator0.1.4をリリースしました。
ちょっとアップデートをミスり、番号1個飛ばしのリリースです。

修正点は以下です。

  1. ライセンスをGPLに変更
  2. 対応するFirefoxのバージョンを2.0-3.0.*に変更(今までは1.5〜としていたものの、実質テストできていなかったので)
  3. Macでメニューバーから端末を選択しても、defaultにチェックがついたままになるバグを修正
CodeReposで公開中!

そしてようやくCodeReposにコミットしました。
http://coderepos.org/share/browser/platform/firefox/FireMobileSimulator
実は4日前に既にコミットしていたんですが、もうコミットしてくれてる人がいてびっくりです。いまさらだけど人の書いたソースを読むのは刺激になって面白い!
まだドキュメントも何もない状態ですが、興味のある方は細かな修正でもいいのでコミットしてくれるとうれしいです。(でもちゃんとテストはしてね!)
あと、当面のリリース作業などは引き続き僕がやっていく予定です。

自動update対応について

コメント欄で、何で自動updateに対応しないんですか?という質問を頂きました。
Mozillaのadd-onsサイトで公開していると、自動でupdateに対応するはずなんですが、どうもうまく機能していないようです。もしかしたら当アドオンが実験的だからかも?ということで、公式アドオンとして認可されるまではちょっと様子を見ている段階です。お手数かけてすいませんが、もうしばし、猶予を下さい。。。

今日の豆知識

install.rdfのminversionとかmaxversionに使われる2.0.*とかの*は無限大をあらわす。
よって<em:minVersion>2.0.*</em:minVersion>などと指定すると実際の2.0系にはインストール不可になってしまいます。
2.0系に対応するときは素直に2.0と書きましょう。

FireMobileSimulator0.1.2をリリースしました

FireMobileSimulator0.1.2をリリースしました。

修正点は以下です。

  1. 絵文字のimgタグ変換のオンオフをOptionsメニューから切り替え可能とした
  2. ツールバーにアイコンボタンを配置せずにメニューから端末を選択した場合、アイコンが切り替わらないバグを修正

1点目は、サイトのinputタグ属性値に絵文字を使用していた場合に、タグの属性値内にimgタグが展開されてしまうためHTML表示がおかしくなる問題の対策として実装した機能です。
タグの属性値に絵文字が使われているかどうかを判定して、タグの属性値の場合、タグ自体をdivやspanなどに変更して、テキスト属性値に持ってくることも考えたのですが、絵文字変換処理はブラウザでDOMツリーが展開される前、StreamConverterの中で行っているため、ここでタグの属性値が否かの判定を行ってしまうとDOMツリーの展開を二重に行うことになり望ましくないなと思っています。絵文字変換の場所自体をかえた方がいいのかも知れません。どうも難しいなあ。。。

FireMobileSimulator 0.1.1をリリースしました

FireMobileSimulator0.1.1をリリースしました。

修正点は以下です。

  • ページをブックマーク時にブックマークマネージャが開かなくなるバグを修正

Array.prototypeに関数を追加したのが原因でFirefox本体でエラーを引き起こしていたようです。
Firefox本体のソースを引用すると、
[browser.jsより]

  _blockedCommands: ["cmd_close", "cmd_closeWindow"],
  _blockCommands: function SU__blockCommands() {
    for each(var key in this._blockedCommands) {
      var elt = this._element(key);

このfor eachで配列を回しているところに追加した関数オブジェクトも列挙されてしまっていました。
id:amachangが指摘するところの「for in は配列走査のための記法ではない」を見事にFirefoxはやってくれていたようです。
でも、こういった組み込みプロトタイプの書き換えは、オブジェクトを利用する側で書き換えられていることを配慮した作りにするのではなく、書き換えないように配慮するのが通常みたいですね。勉強不足でした

aidesさん、ご報告ありがとうございました!

FireMobileSimulator 0.1.0をリリースしました&お知らせなど

FireMobileSimulator 0.1.0をリリースしました。

修正点は以下です。

  • 絵文字完全対応
  • ツールバー上にボタン配置可能(表示->ツールバー->カスタマイズでボタンを追加可能)
  • メニューにアイコン追加
  • 以下の位置情報送信機能に対応(緯度経度などの情報はOptions->位置情報設定から設定可能)
    • DoCoMoのオープンiエリア機能
    • DoCoMoのGPS機能
    • Auの簡易位置情報送信機能
    • AuのEZナビ位置情報送信機能
  • WMLの一部に対応
    • <wml:anchor><wml:spawn href="xxx">
    • <wml:onevent type="onenterforward"><wml:go href="xxx">
  • HTTPSへのiモードID・UID送信制限
  • DoCoMo端末のCookie送信制限
  • 終了時・アンインストール時に設定をクリアするようにした
    • 端末設定を選択したままアンインストールすると端末設定が元に戻らない不具合に対応するため
  • Option設定の見栄え改善
  • POSTメソッドでDoCoMoのUIDが送信できない不具合対応
  • 端末追加ダイアログでキャンセルボタンを押下しても、新規端末が一覧に追加表示されてしまう(実際には追加されていない)バグを修正


週初に公開した方がユーザーの目に留まり易いかな、とも思ったのですがあえて週末の公開です。
というのも、明日ESPer2008というイベントでこのアドオンのライトニングトークをさせて頂くことになったので、それに発表するネタを事前に仕込んでおきたかったからです。
今回のバージョンアップでは絵文字サポートを強化した他に、試験的にGPSを含む位置情報送信機能に対応してみました。
DoCoMoとAuだけですが、緯度経度などを自分で設定してサイトに送信することができます。
設定が面倒な人の為に、デフォルト値は初台のオペラシティになってます。(ちなみに僕の勤務地です。)
本当はGoogleMapsで位置を選択して情報を自動取り込み、とかやりたかったんですが、ちょっと実装の時間が取れなったので今回は見送りました。

そしてこれを機にCodeReposに公開しようと思っています。(現在アカウントをYappoさんに申請中)
一人で開発を続けるのが結構大変なのと、このバージョンである程度のソースコードの雛形は完成したと考えたのが主な理由です。この先は既存ソースの拡張・改修で、携帯シミュレータとしてかなりの高みにまで行けるんじゃないかな、と。

というわけで開発していただける方を絶賛大募集中です。
モバイル開発者のみなさん、モバイル開発をもっと楽にしませんか?

FireMobileSimulator 0.0.5をリリースしました

FireMobileSimulatorにものすごい数のブックマークをいただいてびっくりです。
鋭意バージョンアップしていく予定ですのでよろしくお願いします。

今回のバージョン0.0.5はバグフィックスですが、次回のバージョンでは現在では一部の書き方しかサポートしていない絵文字表示について、完全対応する予定ですので期待してください。

FireMobileSimulatorのバージョン0.0.5をリリースしました。

Mozillaサイトからダウンロード

Mozillaのアカウント登録を行う予定のない方はこちらからダウンロードしてください。

修正点は以下です。

  1. SoftBankで[1]や[3]などの一部絵文字が正しく表示されないバグを修正

みのるさん、不具合の報告ありがとうございました!