おがさわらなるひこのオープンソースとかプログラミングとか印刷技術とか

おがさわらなるひこ @naru0ga が技術系で興味を持ったりなんだりしたことをたまーに書くブログです。最近はてなダイアリー放置しすぎて記事書くたびにはてな記法忘れるのではてなブログに移行しました。

クリエイティブ・コモンズ・ライセンス
特に断りがない場合は、本ブログの筆者によるコンテンツは クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。

短期集中連載? LibreOfficeをWindowsで開発してみよう:その⑤ 不具合直して? みたよ

GWの間にLibO開発できる環境をWindowsで作ろうの連載5回目。さてGWやらも本日で終わり、なのでこの短期集中連載もさしあたりの最終回。

過去記事:第1回 第2回 第3回 第4回

せっかく開発環境作ったのになんにも触らないのもアレなんで、適当なバグを直してみようと。ターゲットにしたのはこれ。

bugs.documentfoundation.org

この不具合なんですが、平たく言うとExcelで作成した「セルの書式設定で大字(12345……を壱弐参四五……って書くやつ)を指定したセルが、LibO Calcで開くと大字にならないってものです。

Excelで大字表示ってどうやるんだろ……って調べてみると、たとえばこのサイトがヒットしたんですけど:

www.kenzo30.com

書式記号に [DBNum2] って指定すればいいらしいです。

Excelの書式指定子(Modifier)、Calcでも指定できるので指定してみる……と、

f:id:naruoga:20200506210339p:plain
書式指定子 [DBNum2] 指定

ホントだ。大字にならないですね。ということでこれを追ってみることにします*1

ソースを検索して該当部分を探す

最初はやみくもにソースを検索して該当部分を探してみましょう*2

ソースの検索は OpenGrok でも git grep でもよいですが、まあせっかくなのでVS2019上で検索してみることにします。 Ctrl-Shift-F を押してソリューション内検索ダイアログを開いて "DBNum2" を検索します。

見つかったのはテストコード、コメントを除くと /svl/source/numbers/zformat.cxx だけ。名前からいってもそれっぽい。ということで中を覗いてみます。

デバッガを使いつつなんとなく眺める

パッと目に入るのは、 SvNumberformat のコンストラクタ。 こいつもまあ相当長いメソッドなのですが、要は書式指定子の文字列をパースして [DBNum2] なら 2 を取り出して保持しておく処理っぽいですね。

あと DBNum というキーワードでなんとなくコードを眺めると:

sal_uInt8 SvNumberNatNum::MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, bool bDate )
sal_uInt8 SvNumberNatNum::MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, bool bDate )

というペアのメソッドが目につきます。なにやら内部的に DBNum と NatNum なるものを相互に読み替えているらしい。 試しにデバッガで前者にブレークポイント設定して*3 DBNum2 を設定してみたら呼ばれてますね。なるほど。 私はこんな風にブレークポイントしかけて確かにこれが見るべき処理かって確認するのよくやります。 机上で追い込むの苦手なので……。

そこで、おっと思ったのが、さっきのテストでセルの書式設定に [DBNum2] とやったやつ。 あれを保存して再度読み込みなおすと、 [NatNum4] という書式指定に代わってしまう。

f:id:naruoga:20200506215618p:plain
書式指定が変わってしまう

ここでようやっと、仕様確認しようと思いつきました(遅い)。ヘルプを "DBNum2" で検索すると、このページがヒットしました。

help.libreoffice.org

「Displaying Numbers Using Native Characters」とあるとおり、NatNum というのはNative Numberなんでしょうね。 LibOの書式指定のネイティブはこっち。

で、Excel(OOXML)からインポートしたり、手打ちで書式指定 DBNum2 とかした場合は、適切なNatNumに変換して内部的にはそれを使って処理する……と。なるほどね。 エクスポートするときには逆に NatNum から DBNum に書き戻すのでしょう。

さてヘルプを見ると、…… DBNum2NatNum4 に対応するということですね。 それは、ODSで保存して読み込み直すときの結果と符合しますね。なのでここに間違いはないと*4

じゃあそうなると、書式指定をもとに実際の表示文字列を組み立てるところ、それが問題あるということでしょうか。 表示文字列を組み立てるところ、それって多分ですけど、普通の実装なら、 セルの内容を渡したら文字列が返ってくるメソッドを用意するんじゃないでしょうかね*5

ということで、ソースコードgrepして(ここはVS2019使わないんかい!) zformat.cxx の中で戻り値が OUString なものをgrepして、中のぞいて、あーそれっぽいと思ったのがこの二つ。

OUString SvNumberformat::impTransliterateImpl(const OUString& rStr,
                                              const SvNumberNatNum& rNum ) const
{
    css::lang::Locale aLocale( LanguageTag( rNum.GetLang() ).getLocale() );
    return GetFormatter().GetNatNum()->getNativeNumberStringParams(rStr, aLocale, rNum.GetNatNum(),
                                                                   rNum.GetParams());
}

void SvNumberformat::impTransliterateImpl(OUStringBuffer& rStr,
                                          const SvNumberNatNum& rNum ) const
{
    css::lang::Locale aLocale( LanguageTag( rNum.GetLang() ).getLocale() );

    OUString sTemp(rStr.toString());
    sTemp = GetFormatter().GetNatNum()->getNativeNumberStringParams(
        sTemp, aLocale, rNum.GetNatNum(), rNum.GetParams());
    rStr = sTemp;
}

どっちも GetnativeNumberStringParams() なるメソッドを読んでるわけですが、ここはVS2019でステップ実行でステップインして飛びますと、 最終的には i18npool/source/nativenumber/nativenumbersupplier.cxxNativeNumberSupplierService::getNativeNumberString() メソッドに来るわけですね。

で、こいつをデバッグ実行しつつ追うと、

    switch (nNativeNumberMode)
    {
        ...
        case NativeNumberMode::NATNUM4: // Text, Lower, Long
            number = &natnum4[langnum];
            break;

という処理があって、ここで number という変数に入ってくるのは、すでに大字ではない通常の漢数字……ふむぅ。……ん?

ここで仕様(というかヘルプ)を再度確認

はい、私のよくなかったところ。 おもむろにソースを見る前に、「解くべき問題は果たして何か(何が正しいふるまいか)」を確認する必要がありましたね。

で、ヘルプ再度確認すると、いやー間抜け:

f:id:naruoga:20200506230700p:plain
NatNum4 は modern long Kanji text !

NatNum4 は modern だって書いてあるじゃー、ないですか!

なのでヘルプの記述が仕様として正しいなら、今の動作は完全に正しい。そして、古いヘルプ:

help.libreoffice.org

を見ると、この動作は3.3から……というかOpenOffice.orgのころから変わっていない、と思われます。

でもおかしいですよね、Excelでは DBNum2 は大字なのだとしたら、当然LibOではそれに対応する NatNum5 じゃないと、バグ起票されたようにExcelとの互換性がないということになってしまう。うーん。わからん。

目をつぶって直す

まあいいや、もし仮にこいつ直すとしたらどうするか。

結果としては DBNumXNatNunX の割り当てだけが問題ってことになったので、前述の:

sal_uInt8 SvNumberNatNum::MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang, bool bDate )
sal_uInt8 SvNumberNatNum::MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLang, bool bDate )

この二つを直せばいいということになります。

本来ならすべてのマッピングを見直す方が適切なのかもわからないですが、さしあたりはこの問題だけ直してみます。 以下diffだけだと若干情報足りないので手で補った嘘diffです。

@@ -170,7 +170,7 @@ sal_uInt8 SvNumberNatNum::MapDBNumToNatNum( sal_uInt8 nDBNum, LanguageType eLang
          switch ( nDBNum )
          {
          ...
          case 2:
             if ( eLang == primary(LANGUAGE_CHINESE))
                 nNatNum = 5;
             else if ( eLang == primary(LANGUAGE_JAPANESE) )
-                nNatNum = 4;
+                nNatNum = 5;
             else if ( eLang == primary(LANGUAGE_KOREAN) )
                 nNatNum = 2;
             break;

こちらは DBNum2NatNum4 にして、

@@ -238,7 +238,7 @@ sal_uInt8 SvNumberNatNum::MapNatNumToDBNum( sal_uInt8 nNatNum, LanguageType eLan
          switch ( nNatNum )
          {
          ...
          case 4:
             if ( eLang == primary(LANGUAGE_CHINESE) )
                 nDBNum = 2;
             else if ( eLang == primary(LANGUAGE_JAPANESE) )
-                nDBNum = 3;
+                nDBNum = 2;
             break;
         case 6:
             if ( eLang == primary(LANGUAGE_CHINESE) )

こちらは逆に NatNum4DBNum2 に戻しているだけ。あー、超簡単だ。

で、この変更を入れてビルドしたやつで、バグ報告についてたファイルを開いてみると……。

f:id:naruoga:20200506233209p:plain
6.4だと大字になってない

f:id:naruoga:20200506233429p:plain
直したやつだとちゃんと大字になる

直ってますね!

もし……仮にもし、これをパッチに出すとすると、

  • まずはあるべき仕様を日本コミュニティで議論(メーリングリストかな?)。
  • 上記に基づき、DBNum2 以外に対する処理も書く。
  • ユニットテストでこの処理を確認しているものがあるげなので、直すなり、もしこのケースを確認してないなら追加するなりする。
  • ヘルプも直す。
  • コミット整えて、gerrit に push

ってな感じですかねー。

まあともかく、開発環境作ってリアルな問題を(少なくとも技術的には)解けるところまではいったので、 ゴールデンウイークとしてはまあまあの成果かな?

せっかくなので、これっきりにしないで定期的に開発にかかわっていきたいですね!

*1:なお調査しなくてもhimajin100000さんがコメントで書いてくださってるんですが、それはなんというか、練習なので、カンニングしない方向で……。

*2:慧眼なる読者の皆様ははこれが誤った手順であることにお気づきかと思います……。詳細はのちほど。

*3:個人的な言葉づかいで「ブレークポイントをはる」っていうんですが、この「はる」は張るなのか貼るなのかそれ以外なのか。

*4:もう気付いている人はいらっしゃると思いますがこれも伏線……です。

*5:引数で渡したオブジェクトの参照に値詰めて戻る実装もあるけど、文字列なら普通returnします……よね?

短期集中連載? LibreOfficeをWindowsで開発してみよう:その④ Visual Studio開発落穂ひろい

GWの間にLibO開発できる環境をWindowsで作ろうの連載4回目。環境作るだけじゃなくてできればバグつぶしてコミットするところまで行きたい。

過去記事:第1回 第2回 第3回

今日……というか昨日か、はあんまり進んでません。 なぜならSNSなどでご覧になった方はいるかもしれませんが、開発用のノートPCのHDDをSSDに換装したら、環境が全部ふっとんじゃったからです。 それを戻すのに時間がかかってこっちの作業あんまり進められませんでした。

なのでその際に気づいたメモなどを書いてお茶を濁します。 いちおうソースコード眺め始めてはいますが、まだ目立った成果はないので……

  • ディスク換装したのですが \cygwin\ 以下をまるっと古いディスクからコピーすればいいかと簡単に考えてましたがダメだったみたいです
    • git リポジトリでどうやってもuntracked changeがなくならない……
    • checkout -fcleanstash / stash drop もダメ
    • しょうがないので dev 以下捨てて lode 直下で ./setup --dev --force やり直して再ビルドしました
  • VS2019ソリューションが読めない
    • 言語パック切り替えるの忘れてたので English にしたら通りました
    • ただこれ、言語パック忘れじゃなくて、なにか VS Installer でちゃんとインストールできてなかったものがあって、 言語パック切り替えでそれがちゃんと入ったとかなのかも
    • 実は今回 workload の導入にも chocolatey 使ってみたんですけど、そいつが途中で刺さっちゃったんでアボートしたんですよね
      • ビルドとおったので大丈夫かな? と思ってたのですが、大丈夫じゃなかったのかも
  • デバッグ実行起動遅い話は、SSD化でだいぶ改善しました。やっぱり金の力は偉大だ

今はそんだけです。夜の報告でコードの解析結果とかお見せできたらいいな。

LibreOffice Asia Conference 2019 Tokyo 基調講演の紹介

去年行われましたLibreOffice Asia Conference 2019 Tokyo

conf.libreoffice.jp

の基調講演2本の字幕を聞き取りなおして日本語訳もつけたので、 せっかくだからもっといろんな人に見てほしいということで宣伝エントリーを書くことにしました。

言わずもがなですがわたくしの個人ブログに書いてることからお分かりの通り、 ここに書いてあることはLibreOffice日本語チーム、あるいはTDFをいかなる意味でも代表した発言ではござりませぬ。 あくまでもLibreOfficeというプロジェクト、コミュニティに好感を持つ一個人の意見としてお読みくださいませ。

さておき。動画については字幕ONにして、言語を日本語にしてご覧くださいね。

Mark Hung: LibreOffice CJK Bugs, Fixes, and Stories.

www.youtube.com

Mark Hung氏は台湾のLibreOffice開発者です。 主にLibreOffice Writerにて、を日本語で利用するには欠かせない、 アジア言語(いわゆるCJK; Chinese, Japanese, Korean)ならではの組版規則、ルビ、縦書き、BMP外のUnicode文字の扱いなど、さまざまな不具合を修正してきました。 最近ではWriterだけでなく、Impressのアニメーションの改善などにも取り組んでいます。

この講演では、なぜ彼がLibreOfficeに取り組むことになったか、 そしてどういう問題に取り組んできたかを、ストーリー仕立てで話してくれました。

Markのすごみというかは、自分の解ける範囲の問題を着実に解いて、それを意識して広げているってことです。

例えばルビの不具合、彼が直してくれたというときには、そうかー台湾でもルビ使うのかーって素朴に思ってたんですけど、 そうじゃなくて、自分が使ってないけれども領域が近い(CJKな問題)、 直せそうな問題を選んで取り組んだということをこの講演で言ってて、 なんというかそういう姿勢がすごいですよね。

LibreOfficeが持つCJKなさまざまな機能について振り返るという意味でも面白いですし、 それから、彼のLibreOfficeのストーリーのきっかけとなる、 Apache OpenOfficeで数週間放っておかれた不具合がLibOでは翌日レビューされて、 それが理由で組織がLibOを採用した……なんて話も面白いです。

あんまり弁が立つほうじゃないので、TED的なうまさはないですし地味に聞こえるかもしれないですが、 私としては、淡々とした口調であるからこそ、 なおかつ自分の活動を声高に主張しないからこその、 強さがあるなあと思いました。

彼の活動を日本に紹介したい、だから日本で講演してほしい。 それはずっと思ってきたことだったので、 とっつきの派手さがないから動画見られていない、 SNSとかでもあまり言及がない、ということなら、 それはすごいもったいないと思うのですよねー。

ので、とにかく見てほしいです。OSSへの貢献のありかたという意味でも興味深いです!

Italo Vignoli: LibreOffice, the many different faces of a global community

youtu.be

  • タイトル邦訳:LibreOffice、グローバルコミュニティの多様な側面
  • 発表資料(PDF): 英語 日本語

Italo Vignoli氏は、LibreOfficeを法的・財務的に支える非営利組織であるThe Document Foundation(以下TDF)の創立メンバーで、 マーケティング・広報担当コンサルタントとしてTDFと契約しています*1。 TDFが行っているLibreOffice認定制度を行う認定委員会の共同委員長でもあります。

LibreOfficeプロジェクト、プロダクトの説明もしていますが、それよりも、 LibreOfficeを取り巻く世界と、そこにおいてLibreOffice/TDFは何を目指して何をしてきたかという話が、 とても興味深いです。

ソフトウェアライセンスの輸出入の多寡で見る世界地図というところは実に衝撃的で、 LibreOfficeを使ってなくても、日本においてソフトウェアにかかわっている人であれば、 この話を聞くだけのためにぜひ見てほしいです。

またLibreOfficeの前身プロジェクトであるOpenOffice.orgとSun、Oracleの関係、 OpenOffice.orgが商標を譲渡したApache OpenOfficeIBMの関係なんかも、 改めて聞くと面白いんじゃないかと。

まあItaloという人はとにかく弁が立つ人で(そういう意味ではオープニング基調講演のMarkとは対照的)、 若干あおりが入ってるところもありますが、 笑いが絶えない、funかつinterestingな講演でした。

Lothar Becker: Certified as a LibreOffice professional - a win/win/win situation for the community

youtu.be

※Italoの講演の続きとなります。

  • タイトル邦訳:LibreOffice 専門家として認定をうけること - コミュニティにとってWin / Win / Win な状況
  • 発表資料(PDF): 英語 日本語

Lothar Becker氏は、Italoと同じくTDFのLibreOffice認定委員会の共同委員長です。 OpenOffice.orgの時代から、ドイツでもっとも古い移行案件を実施し、またOpenOffice.orgの認定制度を立ち上げるなどの活動をしてきたそうです。 なお、この当時は違いますが、今はTDFの議長を勤めています。

で、この講演は、彼の実績から、LibreOfficeのビジネスとエコシステムとコミュニティ、 そして認定制度についてのものでした。

ええと、正直に申し上げます。わたくし、 Lotharの話、LibreOfficeのグローバルなカンファレンス(LibreOffice Conference、通常LibOCon)で聞いて、 いまいちピンとこなかったんですよね。 じゃっかん抽象論っぽく聞こえて。

というのは、やっぱりあれじゃないですか、 LibreOfficeへの移行を(その動機はさておき)検討した場合、 「いやそんなことできませんよ」となる理由の一つは、 専門家によるサポートが受けられないことだと思うんですよね。 で、なぜサポートできる専門家がいないかというと、 平たく言うとそれでご飯が食べられないからです。市場がないか小さいから。 これってまさに鶏と卵のジレンマですよね。 そこに対するよい答えが、ないように思ってたのです。

でも、今回書き起こしのために時間かけて聞いたら、 自分で自分に「日本市場には適用できない」って言い訳しちゃってたのかもしれないです。

うーん今のところ考えまとまってないのでうまいこと言えないですけど、 まあ自分としてもうちょっとできることあるんじゃないかな、 人のせいにしてないで、そういうことやらないとなーと思える講演ではありました。

また、LibreOfficeの認定制度についてですが、 オフィスソフトの認定制度というとMSさんのMOSとかそういうのがぱっと浮かびますが、 そういうものとは少し違うんですよね。 その点、ちゃんと説明があったのもよかったと感じました。

……ということで三つの基調講演を紹介しました。

それぞれ、少しずつベクトルが違って面白い講演だったと思います。

面白いな、と思ってくださったら、ぜひ高評価、よろしければチャンネル登録もお願いします*2

*1:人呼んでTDFのゴッドファーザー

*2:YouTuberか!

続きを読む

短期集中連載? LibreOfficeをWindowsで開発してみよう:その③ Visual Studioで開発できるようにする

今回も夜までの更新間に合わなくて翌日朝更新。だって試行錯誤のためにフルビルドやり直しになっちゃったんだもん……。

GWの間にLibO開発できる環境をWindowsで作ろうの連載3回目。環境作るだけじゃなくてできればバグつぶしてコミットするところまで行きたい。

過去記事:第1回 第2回

本日は、LibreOfficeはちゃんとIDE連携があるので、そいつを使ってVisual Studio 2019 Communityで開発できるようにしてみましょう。

先に結論:

  • ./autogen.sh 実行時に --enable-debug 忘れずに。
  • makeに vs2019-ide-integration ってターゲットがちゃんとあるのでそれを使おう。

VS2019向けソリューションの作成

LibreOfficeの開発環境の各種IDE連携については、TDFのWikiにちゃんと説明があります。

wiki.documentfoundation.org

で、Visual Studioの説明を見てみますと、どれどれ……。

For Visual Studio 2017:

make vs2017-ide-integration

For Visual Studio 2015:

make vs2015-ide-integration

あれ? VS2019の説明がない。

まあ、とりあえずやってみましょう。

make vs2019-ide-integration

お、通った! これはドキュメントが更新されてないってことですね*1

見ると、ちゃんとVSで読めるソリューションファイルできてる。素晴らしい。ではあとはVS 2019で読み込めばいいのかな?

って、Wikiを見ると、

Note:

You need to build with --enable-debug in order to generate the Visual Studio IDE integration.

ってあるけど……なくても通っちゃったから別にいいのかなー。

VS2019で読み込んでみる

ということで、生成されたソリューションを読み込んでみました……えいっ。

……いけました!

デバッグ実行を試してみたら、ちゃんと自前ビルドしたLibreOfficeも起動します。おーーー。 ただ、起動までが猛烈に遅いんですけどこれは仕方ないのかなあ……。

しかしデバッグができない……。

では、ためしに適当なところにブレークポイント張って、デバッグ実行できるか試してみましょう。

というのはもちろん、さっきのドキュメントの注意書き「--enable-debug しないとだめだよ」が気になってるからですが。

結果をいうとだめでした。 ロジック上はまず通るだろうと思うところにブレークポイント張っててもすこっと抜けちゃう。 ブレークポイントにマウスカーソル当ててみると「シンボル読みこめないからこのブレークポイント無効だよ」みたいなことが書いてある(細かな文言メモってなかったです、すみません)。

あーそうなんだー、やっぱ --enable-debug ないとだめかー。

ということで、まずはVSを閉じてから、

./autogen.sh \
  --with-lang=ALL \
  --enable-64-bit \
  --with-jdk-home=/cygdrive/c/Program\ Files/AdoptOpenJDK/jdk-8.0.252.09-hotspot/ \
  --enable-debug

としといてから、念のため make clean して、

make && make vs2019-ide-integration

して一晩放置しました。

再びチャレンジ……うまくいった、か?

さて一晩経って処理終わってたので、再びVS開いてソリューションを開きなおし、F5キー叩いてデバッグ実行……ん?!

なんか関係ないところで例外吐いてブレークするんですけど……?(OpenCLがどうとかこうとか)

が、しかし、例外吐いてブレークするということは、デバッグは正常に動いてるということになります。

なので、「一回デバッグなしで起動しておいて、起動後デバッグアタッチする」という方法でやってみたら……。

f:id:naruoga:20200504100733p:plain
デバッグブレークできた

おお、ちゃんとブレークしますね。

ということで、Visual Studio 2019で無事デバッグできるようになった。よかったよかった。

なお、さっき書いた「なんか関係ないところで例外吐いてブレークする」は、一度デバッグ実行できるようにあったら再発しなくなりました……なんぞこれ。 初回起動時にしか通らないロジックとかなのかなあ。 まあ、支障はないので、とりあえず放置することにします(弱い)。

難点

とにかくデバッグ実行の起動がすごく遅いです。

LibOのソースの構成は、内部でたくさんのサブコンポーネントがあるわけですけど(参照: Development/Code Overview - The Document Foundation Wiki)、 こいつらが全部DLLとなる関係で、実行のたびに各DLLのビルドプロセスが走るみたいで、 まあその数が50個ぐらいあるわけですから、ソースに変更がない(ビルド不要)という判定をするだけでもだいぶ待たされます。

これ、なんとかならんのかなあ……。そこらへんはおいおい調査ですかね。

できれば、今日は具体的にソースを読み解いて問題を解くところまでやりたいですね。頑張りましょう。

*1:Wikiだから書いちゃえばよさそうだけど、開発素人なので勇気が出ないです(苦笑)。

短期集中連載? LibreOfficeをWindowsで開発してみよう:その② ビルド通りました、小ネタ紹介

いきなり集中連載1日落としてるじゃねーかってすみません。だって、ビルド通すのに苦戦してたんですもの……。

そんなわけでGWの間にLibO開発できる環境をWindowsで作ろうの連載2回目。

過去記事:第1回

今回は前回にも増して行き当たりばったりなので、最適な答え出してる自信ないです……。

ビルドしてみよう!

前回で autogen.sh を通すところまではできているので、あとは同じディレクトリで:

make

するだけ……なんですが、2点ほどハマりました。

submodule "translations" の取得に失敗してビルドがこけたあと回復不能

これがねー、けっこう解決に時間要しました。

正直、LibOのソースコードが置いてあるgerritですけど、 こいつがどうも能力いっぱいいっぱいなのか、それとも我々極東から離れて遠いヨーロッパにサーバーがあるせいなのか、 大きなリポジトリのcloneがタイムアウトでコケることがあるんですよね*1

で、LibreOffice coreのリポジトリは三つのsubmodule*2 があります。 そのうちの一つ、ウェブ翻訳システムWeblate の成果を取り込む translations というサブモジュールがありまして、 こいつはcloneしたあとのファイル数が23000ぐらいある、まあまあでかいリポジトリです。

なので、5/1の記事を書いた後、寝る前に make 叩いてビルドして、朝起きて結果見たら…… translations を取ってこれなくてビルド落ちてたんですね。

これは、まー、あー、しょうがないか……で、もう一度 make 叩いたのですが。 何度か試してるうちに、なぜか translations が正常にとってこれなくて空っぽなままなのにビルドが進むようになってしまい、 当然 "translations" 以下のファイルがないので途中で落ちてしまう……えー。なんでー。

ここもいろいろ試行錯誤したんですけど、結論からいうと以下のコマンド叩いたら復活できました。

git submodule deinit translations
git submodule init translations

要はいちどsubmoduleと、リモートリポジトリの紐づけ外してもう一度付けなおすみたいな感じですね。

これでもう一度 make 叩いたら、無事、translations の取得はできて*3、ビルド流れ始めました。やった!

Visual Studio 2019のコマンドラインツール( cl.exe とか)のメッセージを英語にする

で、ビルドの途中経過見ると、

□□□□: □C□□□N□□□[□h □t□@□C□□:        C:/cygwin/home/naruhiko/lode/dev/core/workdir/UnoApiHeadersTarget/offapi/normal\com/sun/star/chart2/data/XDataSequence.hdl
□□□□: □C□□□N□□□[□h □t□@□C□□:         C:/cygwin/home/naruhiko/lode/dev/core/workdir/UnoApiHeadersTarget/offapi/normal\com/sun/star/chart2/data/LabelOrigin.hdl

こんな感じになっちゃってます。 あーなるほど、VS2019同梱のコンパイラ cl.exe とかが日本語吐くからだな。

じゃあ、英語にしましょう。 最初この↓ 記事を参考にしたんですが(VS 2017の記事だけど手順は一緒かなって)、

usagi.hatenablog.jp

うまくいかなかったので*4、 もうあたま来て、日本語の言語パック消して英語のに入れ替えちゃうことにしました。

言語パックの追加削除はVisual Studio Installerで行います。前回の記事だと

Visual Studio 2019起動して、「コードなしで続行」選んで、ツール > ツールと機能の取得 を開きまして。

という動線を紹介しましたが、素直にVisual Studio Installerを起動>「Visual Studio 2019 Community」を選ぶ、でもいいです。

で、「言語パック」タブにて「英語」をチェックして、代わりに「日本語」のチェックを外して「変更」。

f:id:naruoga:20200503075132p:plain
日本語を消して英語だけにしちゃう

試してみますと、

>"c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x64\cl.exe" /?
Microsoft (R) C/C++ Optimizing Compiler Version 19.25.28614 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

                         C/C++ COMPILER OPTIONS


                              -OPTIMIZATION-

/O1 maximum optimizations (favor space) /O2 maximum optimizations (favor speed)
/Ob<n> inline expansion (default n=0)   /Od disable optimizations (default)
/Og enable global optimization          /Oi[-] enable intrinsic functions
/Os favor code space                    /Ot favor code speed
/Ox optimizations (favor speed)
/favor:<blend|AMD64|INTEL64|ATOM> select processor to optimize for, one of:
    blend - a combination of optimizations for several different x64 processors
    AMD64 - 64-bit AMD processors
    INTEL64 - Intel(R)64 architecture processors

わーい。英語になった。

巻き添えとして? VS2019のGUIも英語になっちゃいますが、まあ、いいですよね*5

あと、今思ったのですが、一度ビルド通した後はVS2019統合で開発できる*6 から、この手順要らんかった気がするな……。

動いた!

まあそんなわけで待つこと……どれぐらいだろ? 1時間よりは長くて8時間よりかは短い*7 感じかなー。

前にビルドしてたのはThinkpad X220 (Ubuntu)で4時間ぐらいだったかな、マシン早くなったのでもうちょっと早いかと思ってましたがHDDなのがいけないのか。

ともかく私家版ビルド、無事動きました! ビルドしたcygwinターミナルにて instdir/program/soffice & で起動できます。

f:id:naruoga:20200503080026p:plain
ビルドしたLibreOfficeのAbout画面

このリリースはnaruhikoが提供しました。

が誇らしい? ですね。

まーよかったよかった。ではまた次回の連載記事をお待ちください!

*1:前回紹介したlodeの導入手順も、coreのコードcloneしてくるのでその可能性はありました。私は問題なくできましたが。

*2:submoduleがわからない人はgit submoduleでググりましょう。私submoduleの使い方自信なくて毎度ググってる……。

*3:ものすごーーーーーく時間かかりましたけど。

*4:VS2019の機能で開発コンソール開くと英語になるのでよしよしって思ったら、 コマンドプロンプトから実行すると日本語のまま。今考えると環境変数とか見てるのかもしれない。

*5:というか、最初からVS2019英語で導入すればよかったのでは……?

*6:……たぶん。さりげなく次回予告ですが今日はこれを試す予定。

*7:幅あってすみません、別のパソコンで作業してほっといてたら、いつの間にか終わってたので。

短期集中連載? LibreOfficeをWindowsで開発してみよう:その① ビルド環境の構築

GWでヒマ? なのでLibreOfficeの開発というかバグ直しみたいなのに挑戦してみたいですね。 先日買ったThinkpad T470は結局しばらくWindowsで運用することにしたので、じゃあWindowsで開発に挑戦してみましょうと。

ということで短期集中連載開始。途中で力尽きたらごめんなさい。

有識者が皆様にノウハウをご教示するみたいなものではなく、むしろ私の作業メモ。なので嘘とか間違いもあるかも……。

さてと。初回のこれはビルド環境の構築。 といってまだビルドはできてません。 ./autogen.sh が通ることを確認したところまで。

Windowsの環境作ったの記憶にないほど昔か、もしかして初めてなのですが、今はlodeあるんで楽ですね。

wiki.documentfoundation.org

でもlodeだけでは環境できないので、以下も参照して必要なものも入れないといけません。

wiki.documentfoundation.org

Visual Studio 2019 Communityのインストール

最初はBuilding LibreOffice on Windows with Cygwin and MSVC: Tips and Tricksの方を参照しつつ。

Visual Studioをインストールします。私はchocolateyでさくっと。 管理者モードで実行したコマンドプロンプトにて:

C:\WINDOWS\system32>choco search visualstudio2019
Chocolatey v0.10.15
apincoree-vsix 3.9 [Approved]
...
visualstudio2019-workload-nativedesktop 1.0.0 [Approved]
...
visualstudio2019teamexplorer 16.5.4.0 [Approved]
visualstudio2019professional 16.5.4.0 [Approved]
visualstudio2019testagent 16.5.4.0 [Approved]
visualstudio2019testcontroller 16.5.4.0 [Approved]
visualstudio2019buildtools 16.5.4.0 [Approved]
visualstudio2019community 16.5.4.0 [Approved]
visualstudio2019enterprise 16.5.4.0 [Approved]
38 packages found.

ドキュメントによれば「Desktop development with C++」ワークロードも導入せよとのことですので、 たぶん「visualstudio2019-workload-nativedesktop」を一緒に入れることもできると思いますが、 私はいったん本体だけ入れて各種コンポーネントは後入れすることにしました*1

C:\WINDOWS\system32>choco instal -y visualstudio2019community 

次はコンポーネントのインストール。ドキュメントによれば以下のものが必要だそうです。

  • MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.2x)
  • C++ core features
  • Windows 10 SDK (10.0.xxxxx.x)
  • Windows Universal C Runtime
  • C++ ATL for v142 build tools (x86 & x64)
  • .NET Framework 4.x.x SDK
  • C++ 2019 Redistributable MSMs (only required to build MSI installer; not part of the "Desktop development with C++" workload)
  • C++ Clang Compiler for Windows (9.0.0) (not part of the "Desktop development with C++" workload)

Visual Studio 2019起動して、「コードなしで続行」選んで、ツール > ツールと機能の取得 を開きまして。

  • C++によるデスクトップ開発」を選んで、標準でチェックされてるものに加えて「Windows C++ Clangツール(9.0.0 - x64/x86)」もチェック。

ついで「個別のコンポーネント」で、「.NET Framework 4.8 SDK」および「C++ 2019 再頒布可能パッケージ MSM*2」の二つを選んで。

f:id:naruoga:20200501131134p:plain
ワークロード・コンポーネントの導入

これで「ダウンロードしながら変更する」して「変更」を押下するとよい……はず。

JDKのインストール

お次はJDKを入れます。ドキュメントによれば:

Java Development Kit (JDK) Version 8 or later. Make sure to get a 32-bit SDK if you are building for 32-bit Windows, and a 64-bit SDK if you are building for 64-bit Windows (with --enable-64-bit). Grab it from http://www.oracle.com/technetwork/java/javase/downloads/index.html.

とあります。 JDK8以降ならいいみたいなので13EAとか入れるのが男なのかもしれないですが、 弱気なのでJDK8です……へたれ*3。 上を見るとOracleJDKを使うように読めますが少なくともAdoptOpenJDKはいける……はず*4

あとぼーっと読んでたら 「Make sure to get a 32-bit SDK」って部分が目に飛び込んで、えってなったんですが(私だけ?)、 後ろに「if you are building for 32-bit Windows」ってあるので、普通に64bitで大丈夫です。

ということでこれもChcocolateyです。

C:\WINDOWS\system32>choco install -y adoptopenjdk8

インストールできたら確認しましょう。別途コマンドプロンプトを開けて、 java コマンドと javac コマンドの両方が使えればOKと。

C:\Users\naruhiko>java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.252-b09, mixed mode)

C:\Users\naruhiko>javac -version
javac 1.8.0_252

ポリシーの確認

ここからは再びlodeのドキュメントを参照しつつ。

最初にlodeの導入手順ではPowerShellスクリプトを実行しないといけないので、ポリシーで許可されてるか確認して、必要なら許可してあげます。

PowerShellにて:

PS C:\Users\naruhiko> Get-ExecutionPolicy
RemoteSigned

で、ドキュメントを見るとUnrestrictedにしなさいと書いてありますが、たぶんRemoteSignedでも問題ない……というか、私はうまくいったのでそのまま。

cygwinの導入

そして、

https://git.launchpad.net/~documentfoundation/df-libreoffice/+git/lode/plain/bin/install_cygwin.ps1

を取ってきて c:\cyginstall において、PowerShellを管理者モードで起動して実行してあげると。するとcygwinが必要なパッケージともどもインストールされます。

おまけ:CygwinWindows Terminalで使えるように

これで使えるようになったんですがminttyが気に入らんので(?)、 WSLでも使ってるWindows Terminalを使えるようにしました。

手順はQiitaの記事:

qiita.com

のとおりですけど、chere 入れるための setup-x86_64.exec:\cyginstall\packages 以下にあること、cygwin bashのパスは c:\cygwin\bin だということだけ。快適。

lodeの導入

次もドキュメントの通りにやるだけ。cygwin開きまして、

git clone https://gerrit.libreoffice.org/lode
cd lode
./setup --help

これでヘルプが出て、

./setup --prereq

これで「Done.」と出れば依存関係チェック含めてオッケーと。

そしたらお次は

./setup

しまして*5、 これも正常に終わったら、ドキュメント通り ~/.bash_profie に以下の内容を書いて source するかcygwin bash抜けて入りなおします。

export LODE_HOME=/home/<user>/lode
PATH="${LODE_HOME}/opt/bin:${PATH}"

「環境」の作成

lodeには「環境(environment)」という考え方がありまして、 まあ要は開発してるとmasterブランチをビルドする場所と例えば6.4系をビルドする場所を両方維持しておきたいなーとか思うわけですけどそういうのを切り替えるってことですかね。

ドキュメントにしたがって dev/core という環境を作りましょう。

./setup --dev --force

するとLibreOfficeソースコード・レビュー管理システムGerritから ./dev/core にLibreOfficeのコードが一式cloneされてビルドできる環境が整うはず。 Gerritちょっと遅いのでclone結構遅いので、ご飯食べに行くなりお風呂入るなりする前にやっとくといいでしょう。

ウィルススキャンソフトの例外フォルダの設定

で、ウィルススキャンソフトの例外設定しないとパフォーマンスつらいので設定します。

と、あたかも自分はちゃんとやったかのように書いてますが、私自身は後述の autogen.sh のときに怒られて*6、あっと思ってやりました。 具体的な手順は環境によって異なるでしょうから省略。 C:\cygwin\home\<username>\lode\dev 以下を例外フォルダに入れとくとよいと思います。

./autogen.sh の実行

ここまで来たら ./autogen.sh が通れば、まあ必要なものはそろってるんじゃないかといえるので。結果的に私のオプションこんな感じで通りました。

 ./autogen.sh --with-lang=ALL --enable-64-bit --with-jdk-home=/cygdrive/c/Program\ Files/AdoptOpenJDK/jdk-8.0.252.09-hotspot/
  • --with-lang=ALL は全言語有効にしてビルド。まあenとjaだけでもいいんですけどね。
  • --enable-64-bit は前述の「64ビットビルドするならJDKは64ビットね」に書いてあったやつ
  • --with-jdk-home AdoptOpenJDKのインストールした場所

はーやれやれ。

ということで次の記事はデバッグして動いたやつを起動する、ぐらいかなー。 それは(ビルド待ってる時間はかかるけど)手間としては一瞬なはず。

*1:……というか、オンラインイベント参加しつつ作業してたらワークロードなどなど必要だよって記述を見落としてました。間抜け。

*2:こっちはインストーラ開発するんでなければ不要らしいですが、まあいちおう。

*3:8から上のバージョンで何が変わったのか追っかけてないんですよねー。モジュールとかvarとかGraalVMとか?名前しかしらない。

*4:LibOは内部でJDKの名称見てるところがあるので、OpenJDKの全ディストリビューションがOKだとはいえなかったはず。

*5:ここら辺ビール飲みながら作業してたのでちゃんと覚えてない……。

*6:autogen.sh のなかでeicarファイルというダミーウィルスを突っ込んで検知するっぽい、かしこい。

OmegaTのチームプロジェクトでちょっとハマった話

最近お仕事でOmegaT:

omegat.org

を使い始めました。で、社内のGitLabをホストにしてチームプロジェクトを作ったのですが、若干ハマったのでここでメモっておきます。わかってみれば大したことではないんですけどねー。

なお検証したのは今のStandard VersionであるところのVersion 4.3.2です。Latest Versionではどうなのか確認してません。

結論から言うと:

  • GitLabでオレオレ証明書を使うのはやめよう
  • それがダメならパスフレーズなし鍵ペアを用意してそれをGitLab専用にしよう
  • 鍵ペアはed25519じゃなくてRSAで生成しよう

ってーことです。以下時系列。

お断りですが、これ試してたのは会社環境で、この記事書いているのは個人PCなので、メッセージその他は記憶で書いてます。実際のものとは異なることはご了承くださいませ。

GitLabにpushしたリモートリポジトリと紐づけたチームプロジェクトがぶっ壊れる

(注:後から考えると、正確にはぶっ壊れてたわけじゃないんですが、そのときにはそう思ったんですよ……)

手元でOmegaTで翻訳できるプロジェクト作って、まあまあ快適に翻訳できるようになったわけです。

でもほかのメンバーでも作業できるようにするにはチームプロジェクトを作る必要があるらしい。さてどうやって作るのかな。で、ドキュメント調べたら:

omegat.sourceforge.io

あーふむふむ、要はGitリポジトリ作ってそこにいろいろぶち込んでpushして、それをチームプロジェクトとしてダウンロードすればいいのね*1

で、手元のプロジェクトを git init して一式コミットして、社内で立ってる、社内N/WからしかアクセスできないGitLabにリポジトリ作って、そこを git remote add origin git:// ってして push して、じゃあこれを「プロジェクト」>「チームプロジェクトのダウンロード」のURLに指定すればよいと。

f:id:naruoga:20200501095003p:plain
チームプロジェクトのダウンロードポップアップ

……ん? 「.... Auth fail」??? どゆこと? 普通に自分がpushできてる自分のリモートリポジトリなんだから、認証に失敗するとかないと思うんですけど……。

まあとにかく、リポジトリOmegaTからcloneできないってことね。なんだろう、もしかしてやり方がまずいのかな、一度OmegaTで読み込んでごにょごにょする必要があるってことなのかな。 ということで、チームプロジェクト化したと思われたローカルのプロジェクトをOmegaTで開いてみますと、

このチームプロジェクトはバージョン2*2 形式の古いやつだから、今の形式にします?

あ、なるほど、さっきのドキュメントは古いってことか……確かにホームに戻ると「OmegaT 3.1 - 取扱説明書」って書いてあるし。

まあでも移行機能ついてるんだ親切だな、ぽち……え。同じエラーで落ちる。そして、「サーバーと同期できませんでした」といって、OmegaTで開くこともできなくなりましたよ……と。え。マジで。

いやいやいやいや。大丈夫。Gitリポジトリなんだから中に入ってcheckoutなりなんなりすれば元に戻るでしょ……え? Gitリポジトリじゃなくなってる??? .git ディレクトリがないじゃん。えーまじか。

……もちろん、リモートリポジトリからcloneしなおせばモノは残ってるわけですが、翻訳作業が進められなくなる。それは困る。で、ちゃんと調べることにしました。

チームプロジェクトでHTTPSプロトコル使うと動かない

まずは雑に "omegat git auth fail" とかでググる……けど、全然情報がない。

でまあもっと単純に "omegat team project" とかで検索すると……たとえばここ、を参照すると、 大体の例はHTTPSになってる……なるほど。そうなのかな。

じゃあ、URLに https:// を指定すれば……ぐぐ。エラーになりますね。

種を明かせばこれは本当に当たり前な話で、社内GitLabがオレオレ証明書だったから*3。 なので、普通に git clone とかも跳ねられちゃう。普段 git:// でしか使ってないから気づかなかったからというだけ。

Auth failの謎に迫る

しょうがない。このGitLabを使う以上はなんとかしてgitプロトコルを使うしかないわけで、そうなるとAuth Failの謎を解かなければいけません。でもググっても情報がない。

しかしですね、わたくし技術屋としてあるまじき見落としだったんですが、さっきのダイアログ、実は

jgit: .... Auth fail

ってなってたんですよね。jgitっていかにもJavaのgitライブラリじゃないですか。だからきっとこのダイアログはこいつが吐く例外メッセージとかをママ出してるんじゃないか。

ということで "jgit auth fail" でググると……色々出てきた。 で、ヒットした記事をチェックしたら、「鍵にパスフレーズありの場合はこういうコーディングでパスフレーズ渡さないとだめだよ」みたいなStackOverflawの記事を見かけました。 ん?パスフレーズあり?俺の鍵はもちろんパスフレーズありだよ。そしてOmegaTパスフレーズ入れた記憶も、やっぱりないぞ……。

さてはということで "omegat ssh passphrase" とかで検索した……ら。

sourceforge.net

ちょっと古いけど(2015年)、やり取り見てると:

Aaron Madlon-Kay - 2015-09-14

Keys with passphrases will be supported after this development hits trunk. In the meantime, you can use public key authentication now if you remove the passphrase from your key.

ってい書いてあって、

Hiroshi Miura - 2015-09-22

It is nonsense to remove passphrase.

うんうん、ナンセンス! と思ったんですが、どうなんだろ、2015年だしなあ、治ってるかもわからんけど……。

情報見当たらなかったのでまあ試してみようということで、パスフレーズなしSSH鍵ペアを生成しなおして、~/.ssh/config でGitLabのときだけはそいつ使うようにした……ら。

無事OmegaTでも使えるようになりました! やった! ばんざい!

Macで同じことやると「invalid private key」と言われて動かない

で、同僚に「使えるようになったよー」といったら、「なんかうまく動かないんですけど……」とクレームが。

同僚はMacだから? なんだろ? と思いつつ私も検証機でMacあるので、やっぱりパスフレーズなし鍵ペアを使うように ~/.ssh/config 設定し、 リポジトリのcloneできることは確認して、オッケー、ではOmegaTで「チームプロジェクトのダウンロード」する……と、「jgit: ... invalid privatekey」とな。

あわてず騒がず "jgit invalid privatekey" でググりますと……

stackoverflow.com

この記事がヒットしまして、要は:

  • OpenSSHの7.8以降は ssh-keygen で生成するデフォルトの鍵ペアが ed25519 になりました
  • 判断するのは秘密鍵の頭が -----BEGIN OPENSSH PRIVATE KEY----- となってるかでわかる
  • 少なくともOmegaTのjgit(バージョンなのか使う側の実装なのか)ではこの形式の鍵が食えない
  • なので以下のようにして鍵形式を切り替えてあげればOK
ssh-keygen -p -f 【鍵ファイル名】 -m pem -P "" -N ""

で、うまくいきました。

おまけ:環境によってはMacOmegaTJREありバージョンは動かない

これは私じゃなくて同僚がハマったんですが、OmegaT 4.3.2のJREありバージョンが起動時に例外吐いて死ぬという問題があるようです。

ぐぐったら上記JREありバージョンに同梱されてるOpenJDK 1.8.0 u201の問題みたいで、JREなしバージョン使うか、5.2.0ならJRE新しくなってるのでそれを使えばいいみたい。

*1:日本語のドキュメントはOmegaT 3.1ベースで、現在の最新のドキュメントとは異なりますが、まあこのやり方で最終的にはうまくいきました。

*2:3だったかも。

*3:繰り返しますがこのGitLabは社内N/Wからしか接続できないので、オレオレ証明書であること自体はまあ問題ではないのです。いや問題だという方は、すみませんがお目こぼしを。