2018/09/27

Meson 0.48.0でunrecognized arguments: -u --no-rebuild --print-errorlogsを直した話

問題自体は既に解決済みで、0.48.1がリリースされたら修正済みのバージョンが利用できるようになる。それまではpip3で旧バージョンの指定(meson==0.47.2)をするなど、問題が出ている場合は各自対処する必要がある。

  1. 問題の発生
  2. エラーの出力
  3. 原因の特定まで
    1. 補足 (後で調べたもの)
  4. 対処

問題の発生

  • GitHubで開発されているあるソフトウェアをMesonでビルドできるようにする修正の作業を自分の派生リポジトリで行っていたのだが、Mesonのバージョンが0.48.0に上がった後ninjatestがTravis CIのUbuntuでのみ失敗するようになった
  • 自分の場合はTravis CIのmacOSとAppVeyorのWindows環境では発生せず、手元のUbuntu 18.04でも再現せず
  • リリース版が出ているということは、他の誰もこの不具合には遭遇していない?

エラーの出力

  • mesonコマンドの使用法(書式)に続いてmeson: error: unrecognized arguments: -u --no-rebuild --print-errorlogsが表示される
  • 実行しようとして失敗したコマンド行も表示される

原因の特定まで

  1. 表示された3つのオプション文字列の内、長いほうの2つはソースツリーから検索すると見つかり、Mesonはこれらに対応していると考えられるため残りの-uを疑う
  2. testについてのコマンド行の生成処理で文字列-uに関係していそうな部分を探す
  3. それがmesonbuild/backend/ninjabackend.pyで、中ではmesonbuild/environment.pyget_build_command()という関数が呼ばれており、ここでは特定の条件でリストの最初の要素の後ろに-uという文字列が挿入されることを見つける
  4. その “条件” は2つで、1つ目はninjabackend.pyから渡される引数により常に真、2つ目はmesonlib.meson_commandの最初の要素がpythonを含む文字列の場合に真
  5. 類似の事例の報告を確認
  6. Pythonのバージョンも途中疑ったが、Travis CIのUbuntuでエラーを出したのと同一のバージョンを用意しても再現しないし、今回報告されたものはこちらのAppVeyorで動作したバージョンと同一なのでハズレ
  7. 2つの事例のエラーログのコマンド行部分を見ていたときに仮説が浮かぶ
    • 両方ともmesonのコマンドのフルパス内に “python” (“P” は小文字)がある
    • mesonコマンドの親のディレクトリ群のいずれかが “python” を含んだときに失敗するのでは?
  8. 手元の環境でmesonコマンドの親のディレクトリ群のいずれかに “python” が含まれるようにして試すと再現に成功

補足 (後で調べたもの)

  • -upythonコマンドへのオプション指定で標準出力と標準エラー出力のバッファリングを無効化する
  • 0.47.xから後に入った2ee2802より、インストールされたmesonコマンド(拡張子.pyが付かない)を使う際にはPythonのコマンド名がコマンド行の最初には使われずにmesonコマンドへのパス名が内部的に使われるようになったことが関係[1]

対処

  • mesonlib.meson_commandの最初の要素(の全体)に対してではなく、そのパス名の最後の要素(ファイル名部分)が “python” を含むかで分岐するようにさせるため、最初の要素をos.path.basename()で囲むだけ
  • 手元の環境で、問題が再現する状況下でこの修正を適用し、改善を確認
  • Pull Requestは早めに提出[2]し、バグ報告されたページに自分の事例と原理についてのコメントを追加
  • 前述の、同じバグに遭遇した人のリポジトリを派生したものを用意し、パッチが取り込まれた前後のAppVeyorのジョブの出力を見て、パッチの効果を確認・バグ報告を出した方へもそれを報告
[1]: git bisectすると2ee2802から失敗することが分かる
[2]: 以前別の件でバグを報告してから自分でパッチを作ったのだが、仕事の早い人に先を越されて無駄になった悔しい経験があるため