4 活動をした上での失敗談と感想

この記事は2人の大学生がLibreOfficeWriterの一部機能を変えようと格闘した記録の4ページ目(全4ページ)です。 大規模ソフトウェアを手探るという授業の一環で行い、そのレポートを兼ねています。
目次

1. したかったこと

結局はここにあるようにツールボックスを変更しましたが、最初はUndoRedo機能に変更を加えようとしていました。
具体的には、過去の先輩がVSCodeで行ったことを、LibreOffifceのWriterでも実装したいと考えていました。

2. 方針

詳しい説明は過去の先輩がVSCodeで行ったことを見てください。
方針としては、おそらくLibreOfficeVSCodeと同様に操作の履歴を何かしらのスタックに保存していくことでUndo/Redoを実現しているだろうと考えて、それらを木構造に書き換えればいいと考えていました。そのためにまずは、LibreOfficeが具体的にどのように操作を保存しているのかを見ていく必要があったので、まずはそれを突き止めようと(軽い気持ちで)見ていきました。

3.実際行ったこと・つまずいた点

諦めた理由は、思ったより遥かに操作の管理方法が複雑で、その構造を根本から変えることは無理だと考えたからです。
以下では実際どこまでその構造について突き止めることができたのかを書いていきます。
方針としては、Writerにおいてabcと入力したあとにUndoをすることでデバッグをしていき、操作をスタックに入れたりとったりしている部分を突き止めていく予定でした。そして実際に最初にここに書いたようにUndoManager::DoUndoメソッドに目星をつけてブレークポイントを打ってStep Outをして操作を見ていくと、SwWrtShell::Doメソッドに行き、これはSwBaseShell::ExecUndoメソッドから呼び出されたものでした。どうやらここがUndo操作のおおもとだとわかったので、ここからはStep Inを用いて深く探索していきました。
そして深ぼった結果、どうやらpActUndoArrayというポインタ配列に、Undo操作の履歴のポインタを保持していることがわかりました。ここで、VSCodeのように操作の履歴自体をスタックに保持していっているのではなく、それとは別にUndo操作の履歴用の配列を持っていて、さらにそのポインタを配列で保持し、そのポインタ配列をいじることで過去のUndo情報を入手していることから、これは想像よりも遥かに構造が複雑そうだと感じ始めました。そこで実際に自分たちが変更を加えることができるレベルのものなのか見るために、VSCode上でpActUndoArrayを検索したところ、以下のような結果になりました。 まさかのたった1つのファイルに95回もこの配列を参照しているところがあって、なおかつSfxUndoManager_Dataという、Undo関連の情報を管理していそうな構造体を発見したのでその中身を見てみると(上図右)、pActUndoArray以外にも様々な配列や変数が定義されていて、きっとこれ以外にもたくさん配列や変数があり、Redoにも同じ数だけあるということを考えると(しかもそもそも予想と全然違ったわけだし)、この構造をしっかり読み解いて、根本から変更を加えることは不可能だと判断しました。そのためここで目指していたUndo機能の改善は諦めて、1つ前の記事で書いたツールボックスへの変更へ目標を変えました。

4. 実験の感想

  • 今回の実験で初めて大規模なソフトウェアをいじり、とても貴重な経験になりました。ビルドで戸惑ったり、Githubへのpushでつまずいたりと、デバッグをまともに始めるまでに3日もかかって(実験自体が発表日含めて10日間)、いざデバッグをするとなるとどうすればいいかわからかったりと相当焦りましたが、その分残り2日でやっと変更点を加えられたときの嬉しさは相当なものでした。また、実際に自分たちが普段使っているソフトがどのように動いているかを知ることの楽しさも学ぶことができました。変更自体を見ると大したことはできていないですが、実験を通して個人としては相当成長できたと感じています。今後は時間があるときに他の班のブログを参考にして、Pythonなどの中身を見てみたいです。最後に、間違った部分などもあるかもしれませんが、この記事が少しでもLibreOfficeを始めとするオープンソースを触る人の参考になれば幸いです。
  • 私もこの規模のソフトウェアのソースコードを見るのは初めてだったのでプログラムの把握に苦戦しました。開発者向けのwikiページには初心者向けのEasy HacksなどLibreOfficeのコードを書く上で有用な情報が多くありそうだったので、時間をとってきちんと読んでいたらよりスムーズに変更を加えることが出来たかもしれないと思っています。今回は自分たちでどの機能を改変するかを自由に決めましたが、ソフトの利用者らから集められているバグや修正案を参考にしてプログラムを書き、オープンソースソフトウェアの開発に貢献するという方向も良いと感じたので、今回の経験を活かしていつかはそのような改変もしてみたいです。今回書いたブログが読んでいただいた方のお役に立てればと思います。

前ページはこちら

3 LibreOfficeのツールバーの機能を変えてみた

この記事は2人の大学生がLibreOfficeWriterの一部機能を変えようと格闘した記録の3ページ目(全4ページ)です。 大規模ソフトウェアを手探るという授業の一環で行い、そのレポートを兼ねています。
目次

1. 変更したこと

Writerの画面上部はツールボックスと呼ばれ、アイコンをカーソルで選択することでUndoやファイル操作などの動作を行うことができます。一部のボタンではアイコンの右に小さな三角▼のアイコンがあり、そこを押すことによってその動作のメニューを開くことができます。

変更前
そのままでも使うことはできるのですが、私たちはこのカーソルを合わせる→小さいボタンを押す→メニューを選択するという3ステップの動作が必要なことや、小さいボタンを押す際の押し間違いが発生することを減らすためにこの機能を変更しました。下が変更した後の動きになります。
変更後
ここでは、マウスのカーソルをアイコンの上に持っていくだけで自動でメニューが開くようになっています。(画像ではクリックしているようにも見えますが、かざすだけでメニューが展開されています。)本来アイコン本体をクリックすることで行われていた動作は、変更前と同様にアイコンをクリックすることで利用できます。このように変更することによってメニューを出すためのステップが一つ減り、作業をスムーズに行えるようになりました。

2. 変更方法

ツールボックス上でのマウス操作を管理するメソッドとして、core/vcl/source/window/toolbox.cxxToolBox::MouseMoveToolBox::ButtonDownがあります。前者はマウスのカーソルがツールボックス中のアイコン上に来た時の動作を記述したメソッドで、後者はアイコンがクリックされたときの動作を記述しています。今回の変更では、カーソルをアイコン上に持ってくるだけで▼ボタンをクリックしたときと同等の動きをさせるために、前者の中で▼ボタンがあるアイコンの場合は後者のようなメソッドを実行することにします。今回はToolBox::ButtonDownの一部を改良したメソッドToolBox::ButtonHoverというメソッドを新たに作成し、ToolBox::MouseMoveの途中で実行できるようにしました。

メソッドの変更イメージ

3.ソースコード

具体的に変更箇所を見ていきます。
まず、ToolBox::MouseMoveでは、カーソルがどのアイコンに乗っているのかを判別するために、以下のfor文を回して探していました。 探し方としては、図のコメントで書いているように、マウスの座標がどのアイコンの中にあるかというのを、nTempPosという変数を1つずつ増やして1つ1つ見て探しています。 今回私たちがやりたかったことは、カーソルをアイコン上に持ってくるだけで▼ボタンをクリックしたときと同等の動きをさせることなので、このfor文中の指しているアイコンが変わったときに、▼ボタンをクリックしたときのメソッドを呼び出せばいいことになります。そのため以下の図で左側が緑になっている部分を付け足しました。 3111行目で選択されたアイコンにドロップダウン機能がついているかを判定し、真のときMouseButtonHoverというメソッドを実行させています。このMouseButtonHoverは私たちが新しく作ったメソッドで、ここで▼ボタンをクリックしたときと同等の動きをさせます。
MouseButtonHoverメソッドは、MouseButtonDownメソッドから、▼ボタンをクリックしたときに行う動作の部分だけを取り出して作成したものです。
中身は以下のようになっています。

void ToolBox::MouseButtonHover( const MouseEvent& rMEvt, const int nTempPos )  
{   

    Point aMousePos = rMEvt.GetPosPixel();

    // call activate already here, as items could
    // be exchanged
    Activate();

    // update ToolBox here, such that user knows it
    if ( mbFormat ) // False
    {
        ImplFormat();
        PaintImmediately();
    }

    if ( !mpData->m_aItems[nTempPos].mbEnabled ) // True
    {
        Deactivate();
        return;
    }
    
    // update actual data
    StartTrackingFlags nTrackFlags = StartTrackingFlags::NONE;
    mnCurPos         = nTempPos;                                  
    mnCurItemId      = mpData->m_aItems[nTempPos].mnId;      
    mnDownItemId     = mnCurItemId;                           
    mnMouseModifier  = rMEvt.GetModifier();
    if ( mpData->m_aItems[nTempPos].mnBits & ToolBoxItemBits::REPEAT )
        nTrackFlags |= StartTrackingFlags::ButtonRepeat;

    // update bDrag here, as it is evaluated in the EndSelection
    mbDrag = true;

    // on double-click: only call the handler, but do so before the button
    // is hit, as in the handler dragging
    // can be terminated
    if ( rMEvt.GetClicks() == 2 )
        DoubleClick();

    if ( mbDrag )              
    {
        InvalidateItem(mnCurPos);
        Highlight();
    }

    if( ( (mpData->m_aItems[nTempPos].mnBits & ToolBoxItemBits::DROPDOWNONLY) == ToolBoxItemBits::DROPDOWNONLY)
        || mpData->m_aItems[nTempPos].GetDropDownRect( mbHorz ).Contains( aMousePos ))
    {
        // dropdownonly always triggers the dropdown handler, over the whole button area

        // the drop down arrow should not trigger the item action
        mpData->mbDropDownByKeyboard = false;
        mpData->maDropdownClickHdl.Call( this );

        // do not reset data if the dropdown handler opened a floating window
        // see ImplFloatControl()
        if( !mpFloatWin )
        {
            // no floater was opened
            Deactivate();
            InvalidateItem(mnCurPos);

            mnCurPos         = ITEM_NOTFOUND;
            mnCurItemId      = ToolBoxItemId(0);
            mnDownItemId     = ToolBoxItemId(0);
            mnMouseModifier  = 0;
            mnHighItemId     = ToolBoxItemId(0);
        }
        return;
    }
    else // activate long click timer
        mpData->maDropdownTimer.Start();
    // call Click handler
    if ( rMEvt.GetClicks() != 2 )
        Click();

    // also call Select handler at repeat
    if ( nTrackFlags & StartTrackingFlags::ButtonRepeat )
        Select();

    // if the actions was not aborted in Click handler
    if ( mbDrag )
        StartTracking( nTrackFlags );
    
    // if mouse was clicked over an item we
    // can abort here
    return;
}

最後に、新しいメソッドを作成したため、これをヘッダファイルで宣言しなければなりません。したがって、include/vcl/toolbox.hxx内に、

    virtual void        MouseButtonDown( const MouseEvent& rMEvt ) override;
    void        MouseButtonHover( const MouseEvent& rMEvt, const int nTempPos);   // 付け加えた。
    virtual void        MouseButtonUp( const MouseEvent& rMEvt ) override;
    virtual void        MouseMove( const MouseEvent& rMEvt ) override;

このようにMouseButtonDownMouseMoveメソッドが定義されているところに定義を付け加えました。
以上で、マウスのカーソルをアイコンの上に持っていくだけで自動でメニューが開くように変更できました。

4. 変更箇所にたどり着くまで

ここではどのようにして上述のcore/vcl/source/window/toolbox.cxxToolBox::MouseMoveToolBox::MouseButtonDownにたどり着いたかを解説します。
まず、もともと私たちはUndoRedo機能自体に変更を加えようとしていたため、Undo関連の箇所についてはある程度構造や重要なメソッドを把握していましたが、ツールボックス関連のメソッドについては一切知りませんでした。そこで、まずツールボックスをクリックしたときや、ツールボックスにマウスをかざしたときの動作を記述しているメソッドを見つけよう!と考えました。その方針としては、Undo操作にたどり着く前にどこかで操作の判別(Undoをするのか、クリックをするのかなど)をしているところがあると踏んで、Undo操作を行うときに必ず呼び出されるSwBaseShell::ExecUndoメソッドからStep Outを繰り返すことでその箇所を探します。またそこにはおそらくマウスの動作関連の分岐もあるだろうと考え、さらにたどっていき、ツールボックスにカーソルをかざしたときの動作を記述しているメソッドを見つけようと考えました。
したがって以下のように既に見つけていたSwBaseShell::ExceUndoというUndo操作の比較的上の階層(Undo操作を呼び出してそうなところ)にあるメソッドにブレークポイントを打って、ひたすらにStep Outをしていきます。 すると、しばらく遡ると、 ここにたどり着きました。どうやらなにかイベントの種類でswtich文で分岐させている箇所のような感じがします。怪しいのでこのメソッド全体を見ると、 ありました!まさしくnEventというイベントの種類で、switch文で分岐させています。そして見事すご〜く怪しそうなMouseMoveMouseButtonDownというイベントが見つかりました。 これらの中身を見ていきましょう。とりあえずSwBaseShell::ExceUndoはもう必要ないのでブレークポイントを外して、MouseMoveの箇所にブレークポイントを打って、デバッグを続けます。すると、Writerを開くだけでデバッグの画面に戻ってしまうようになりますが、デバッグを進める上では問題ありません。ImplHandleSalMouseMoveメソッドの中身をStep inで見ていき、さらに深く見ていくと、
さらに怪しい場所にいきつきました。中を具体的に見ていきます。 すると、いかにも怪しいMouseMoveというメソッドが!!!そしてこの中身をみると、 たどり着きましたね。ここで、メソッド名に注目すると、ToolBox::MouseMoveとなっていて、ToolBoxクラスのメソッドであることがわかりました。よって、これはツールボックス内でのマウスの動作を扱っているメソッドなのではないかと考えて、一度すべてのブレークポイントを解除して、このメソッドのものだけにしてみたところ、見事ツールボックスにマウスをかざしたときのみ反応しました。

このように、方針として、どこかで今行った操作はクリックやらUndoやらと判定して分岐させているところがあるはず!という考えのもと遡り、そこからマウスの動きと判定している部分を見つけ、そこを丁寧に深ぼっていった結果、求めていたメソッドが見つかりました。また、同じファイル内にツールボックスをクリックしたときの動作などを書いたメソッドもあるはずだ!と見ていった結果、すぐ下に ToolBox::MouseButtonDownにたどり着きました。
前ページはこちら
続きはこちら

2 LibreOfficeのデバッグ(初心者向け)

この記事は2人の大学生がLibreOfficeWriterの一部機能を変えようと格闘した記録の2ページ目(全4ページ)です。 大規模ソフトウェアを手探るという授業の一環で行い、そのレポートを兼ねています。
目次

1. 方法を説明する前に

LibreOfficeは前のページでも書いた通り、そのソースコードは膨大です。coreのなかにはさらに多くのファイルがあり、このページやREADMEに書いてあるような分け方をされているようですが、それらをすべて把握するのは極めて困難です。そこでこのページはどのような方法を用いて自分の関心のある機能に迫っていくかを解説します。また、どうやらLibreOfficeハンガリアン記法という書き方に基づいてコードが書かれていて、これを頭に入れておくと変数がどのようなものを表しているかを推測することができ、コードを読んでいく際に役立つかもしれません。

2. 公式のドキュメントを見て手掛かりを掴もう

いざデバッガを使って、コードを読もう!…とその前に、LibreOfficeが用意しているドキュメントに目を通すことをおすすめします。なぜならLibreOfficeGUIなので、ただ起動するだけではデバッグは始まりません。どこかにブレークポイントを打って、なおかつそのブレークポイントを通るような動作をさせて初めて、デバッグができるのです。じゃあそれっぽいところにブレークポイントをとりあえず打てばいいじゃん...となるかもしれませんが、なにせソースコードが膨大です。何がなんだかぱっと見ではわかりません。そこで公式ドキュメントをしっかり読んで、ブレークポイントを打つところを探すのです。

ここでは各ディレクトリのおおまかな内容が説明されているので、まず触ろうとしているソフト(Writer,Calc,Impressなど)がどのディレクトリなのかを見つけるといいと思います。例えばWriterならsw、Calcならsc、Impressならsdなどと分かれています。そしてそのドキュメントを読めば、プログラムの構造やメソッドの説明がすべて書いてあるわけではありませんが、その一部を大雑把に知ることができるでしょう。もちろん全てを把握するのは無理です。例えばこれはWriterに使われている全てのクラスを一覧にしたものですが、膨大ですよね。なのでおおまかな説明を読んで、関連しそうなメソッドなど目星をつけたら、ブレークポイントを打ってみて、実際にデバッグを開始することをお勧めします。

例えば私たちの場合は、ここに書いたように初めはWriterのUndoRedo機能に変更を加えたかったため、Writerのswディレクトリの説明をまず読みました。ここではsw内の各ディレクトリについて簡単に説明されていて、Writerの根幹部分はsw/source/core内に記述されているそうです。またここに、 とあります。Undo機能はUndoManagerというクラスで管理されているとわかったため、これを目星にブレークポイントを打とうと決めました。 そこで、VSCode上での検索機能を用いて、sw/source/core内でUndoManagerという文字列が出てくるところを検索すると、 のように大量のファイルが出てきます。151件?!と思うかもしれませんが、安心してくだい。ディレクトリをだいぶ絞ったおかげで、13個のファイルしかヒットしませんでした(何も絞らなかったら293個のファイルに3747件と出ます、恐ろしい...)。ここからファイル名的に関係ありそうなファイルに絞り(あとヘッダーファイルもあるのでそれも除外して)、関係ありそうな箇所にブレークポイントをひたすら打っていけばいいのです。今の例では、docundo.cxxがいかにも怪しそうだったので、その中を見ていった結果、UndoManager::DoUndoという非常に怪しいメソッドにたどり着きました。よってとりあえずここにブレークポイントを打ちます。

3. デバッガを使いこなそう

ここまでで怪しいメソッドに目星をつけ、ブレークポイントを打つことができました。ここからは実際にデバッガを立ち上げて、デバッグを開始していきます。デバッガでWriterを立ち上げ、実際にaなどを打ったあとにUndoをしてみると、 このように見事止まってくれます。これで本格的にデバッグができますね!

これからはStep InやStep Outなどを駆使してメソッドからメソッドへと飛び移っていき、少しずつプログラムの内容を把握していきます。メソッドや関数の動作を詳細に知りたいときはStep In、関数がどこから呼ばれていてどのような文脈に位置するのかを知りたいときはStep Outを使うイメージです。関数の働きを知る際には左のサイドバーで変数の中身をチェックしたり、ウォッチ式に入れて動作を観察することも有効でしょう。また、それ以外にも気になる関数を右クリックすると、定義や参照元などに移動できます。これらをうまく駆使してデバッグしていきましょう。

ここで、Step Outをしすぎてしまうと、 のような画面にたどり着きます。vcl/unx/gtk3/gtkdata.cxxGtkSalData::Yieldというメソッドです。これ以上遡ろうとすると、「例外が発生しました」と出てデバッグができなくなるので、注意してください。このYieldメソッドはユーザーからの入力を常に受け付けているスレッド(だと解釈しています)なので、これ以上は遡ることができないのです。ですが、逆に言えば、このメソッドに行き着くまでに様々なメソッドを経由していて、その中には必ずどこかでUndoやRedoなどの操作を決定している場所などがありますから、一度ひたすらStep Outをクリックし続けて処理の流れを大まかに追うのは、全体の処理の流れがわかりやすくなる点でおすすめです。全体を見た上でどこを具体的に見ていけばいいのかを判断すると作業が効率的になると思います。

ここまでデバッグの一般的な使い方を書きましたが、私たちがデバッガを使った時には作業がスムーズにいきませんでした。困った点としては、

  • デバッガで踏み込むとフリーズするときがある(重すぎるから?)
  • 関数が多すぎて1つの動作の始めから終わりまでを追うことができない(1つ1つ丁寧に見ると時間が溶けるので、目星をつけて見るしかないですけど、間違ったものに目をつけると相当時間が溶けます!なのでしっかり見極めてください!)

などです。このソフトへの理解がさらに進めばこれらの問題は回避できるかもしれません。

また、ここではデバッグのノウハウをざっくり説明しましたが、実際にどのような思考でデバッグをするかについては、次の記事の4.変更箇所にたどり着くまでが参考になるかもしれません。

4. 参考になるサイト

5. デバッグノウハウまとめ

詳しくは上で説明しましたが、一応デバッグする際に使いそうなツールをここで簡単にまとめておきます。

  • なにか関数やクラスを検索したい
    VSCodeの検索機能でディレクトリも絞って検索(grepと同じことです)

  • 変化を追いたい変数や、式の値や真偽を知りたいとき
    VSCodeのウォッチ式に入れて観察や、変数の中身を見る

  • 定義や参照元をすぐ見たいとき
    →関数にカーソル合わせて右クリックで選択する(ctrl+クリックでも参照できる)

  • 基本
    →Step In、Step Out、Step Over、Continueをしっかり使い分けることと、左のサイドバーで変数の中身を観察すること
    →適宜参考になるサイトに載せたサイトなどを見たりしてもいいかも?

という感じです。これはあくまでもこの実験で初めてデバッグを知った私たちが、この実験を通して考えたノウハウなのでいろいろと欠けている部分もあると思いますが、同じような初学者のためになればと思います。

前ページはこちら
続きはこちら

1 LibreOfficeをデバッグするまでの下準備(初心者向け)

この記事は2人の大学生がLibreOfficeWriterの一部機能を変えようと格闘した記録の1ページ目(全4ページ)です。 大規模ソフトウェアを手探るという授業の一環で行い、そのレポートを兼ねています。
目次

1. LibreOfficeについての紹介

LibreOfficeとは、オープンソースのオフィスソフトです。この中から、私たちはWriterという文書作成ソフトを選択し、一部機能の変更を行いました。使ったことのない方でも、MicrosoftOfficeのWordのようなソフトと聞けば想像がつくのではないでしょうか。開発者向けのWikiページを見てみると、

LibreOfficeのサイズや複雑さで簡単に圧倒されてしまうでしょう。ソースは多くのプログラミング言語やフォーマットで書かれています — C, C++, Java, Bash, JavaScript, Python, Perl, SQL, Test, XML  — そして約102,000ファイル (すべてのローカライゼーションを除く) で、36,000,000行(ソースコードは7,000,000行)のソースコードで成り立っています。

そのソースコードはなんと3600万行!!この大規模なソフトの中を見てみたい、またオフィスソフトには馴染みがある、という理由から私たちはLibreOfficeの改変に取り組むことにしました。後にこのボリュームによって苦しめられるのですが…

2. 実行環境

作業はすべて下に示すような環境で行いました。

3. ビルドの方法

公式のドキュメントを参考にしながらビルドを行いました。

  1. ソースコードを手に入れる
    LibreofficeソースコードGitHubで公開されているので、ここからcoreというディレクトリを自分たちのGitHubにフォークします。それをローカル環境にクローンすればソースコードを手元で編集できるようになります。
  2. 依存するファイルをダウンロードする

クローンしたらディレクトリの中に入り、ターミナル上でコマンド

$ sudo apt-get install git build-essential zip ccache junit4 libkrb5-dev nasm graphviz python3 python3-dev qtbase5-dev libkf5coreaddons-dev libkf5i18n-dev libkf5config-dev libkf5windowsystem-dev libkf5kio-dev autoconf libcups2-dev libfontconfig1-dev gperf default-jdk doxygen libxslt1-dev xsltproc libxml2-utils libxrandr-dev libx11-dev bison flex libgtk-3-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev ant ant-optional libnss3-dev libavahi-client-dev libxt-dev

を打ち込むことで必要なものはまとめてダウンロードできます。
ちなみに、手順3にて下記のようなエラーが出ることがありますが、これはこの手順2で必要なパッケージがすべてそろっていないことが原因です。

configure: error: Package requirements (fontconfig >= 2.4.1) were not met:

No package 'fontconfig' found

このようになったらsudo apt search (パッケージ名)などで足りていないと思われるパッケージを探し、-devで終わるものをインストールすることでこのエラーを解決できました。しかし私たちの場合は、この方法では追いつけないほど大量のパッケージが足りていなかったので、もう一度、上記の長いコマンドを打ち込むことでエラーを解決しました。結論、パッケージが足りていない場合はもう一度コマンドを打ってみると良いと思います。
3. ./autogen.shを実行する(これは通常のソフトウェアでMakefileを作成するために実行する./configureにあたる操作です)

$ CFLAGS="-O0 -g" ./autogen.sh --enable-dbgutil

を打ちます。ここでCFLAGS="-O0 -g"--enable-dbgutilは後でデバッガを使えるようにするために付けています。CFLAGS="-O0 -g"は無くてもデバッグすることができました。
4. makeを実行する
下記のコマンドをうちmakeします。

$ make -j 8
$ make check 

-j 8は指定された数のコマンドを並列に実行させるためのオプションです。今回の環境ではコア数が8であったため、このようにしています。ちなみに、8つ並列にしてもmakeには4時間ほどかかります(!)ここまでできれば、あと少しでデバッグを開始できます。

4. デバッガの設定

vscodeでデバッガの画面に入ると、左側にcreate a launch.jsonというような文字が出るので、そこをクリックしてlaunch.jsonを開きます。このファイルを下のように書き換えると、デバッガを使えるようになります。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}/instdir/program/soffice.bin", // インストールしたPATHを書く
            "args": ["--writer"],   // Writerを起動するため
            "stopAtEntry": false,
            "cwd": "${workspaceRoot}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

5. Githubで困ったこと

実は初めてソースコードに触れたとき、私たちはLibreofficeGitHubからローカルにクローンし、そこから自分たちのGitHubへpushするという順番で開発に使う共有のGitHubディレクトリを作ろうとしていました。するとpushしようとする段階で、

missingSpaceBeforeEmail: invalid author/committer line - missing space before email

というエラーが出てしまい、pushが完了しませんでした。このエラーメッセージを調べると、同じエラーが質問されているのを見つけました。どうやら過去のコミットが悪さをしているようでしたので、悪さのしていたコミットの中身をみたところ、確かにメールアドレスと名前の間にスペースがなかったことがわかりました(そもそもなんでこれでコミットできてたん?)。よって、こちらの上から2番目の解答に従い悪さをしていた過去のコミットに編集を加え正したのですが、最後に問題のあったコミット以降の全てのコミットをまた戻すコマンドを実行したところ、

denjo@DJ00001:~/libreoffice$  git filter-branch -- --all
fatal: replace depth too high for object 086ff12951769a2fadfc0f92f57c2e4f41108b72

上記のように復元するコミット数が多すぎるため、戻すことができないと出力されてしまいました。そこで問題のコミットがいつのものであったのかを確認したところ、

Date: Wed Jan 26 11:11:11 2011 +0100

なんと2011年...そりゃ無理だ...。ということで、ここでなんともう作業日4日目だったので(発表含めて合計10日です...)、ここで諦めて上記の直接フォークを使う方法で回避しました。 ちなみに公式に書いてあるソースコードの入手方法の3つすべて試しましたが、どれもgithubにpushするときに同じエラーが出て、フォーク以外の方法ではgithubに上げることができませんでした。

それにしてもLibreOffice公式がどうやってこのコミットを通したのかがすごく気になります...。

続きはこちら