Ninja: mtimeがゼロのファイルは存在しないものとして扱われます

作成日 2016年03月25日  ·  14コメント  ·  ソース: ninja-build/ninja

CentOS 7システムの場合:

$ tar xf ome-cmake-superbuild-0.1.0.tar.xz
tar: ome-cmake-superbuild-0.1.0/cmake/GitVersion.cmake: implausibly old time stamp 1970-01-01 01:00:00
$ ls -l ome-cmake-superbuild-0.1.0/cmake/GitVersion.cmake
-rw-r--r-- 1 rleigh lsd 236 Jan  1  1970 ome-cmake-superbuild-0.1.0/cmake/GitVersion.cmake

このソースアーカイブは正しくパックされておらず、単一のファイルのmtimeはゼロです(つまり、Unixエポックの開始)。

$ mkdir build
$ cd build
$ cmake -G Ninja ../ome-cmake-superbuild-0.1.0
$ ninja
[1/1] Re-running CMake...
[cmake re-run repeated 100 times]
ninja: error: manifest 'build.ninja' still dirty after 100 tries

原因:

$ ninja -d explain
ninja explain: output /tmp/ome-cmake-superbuild-0.1.0/cmake/GitVersion.cmake of phony edge with no inputs doesn't exist

明らかに、ファイルは存在します。 touch /tmp/ome-cmake-superbuild-0.1.0/cmake/GitVersion.cmakeタイムスタンプを現在の時刻に更新すると、 ninjaは完全に実行されます。 Ninjaがmtimeがゼロのファイルを存在しないものとして扱っているようですが、これは正しくないようです。 その振る舞いを変えることを考えていただけませんか? これは珍しいコーナーケースですが(ファイルにこれほど古いタイムスタンプを付けるべきではありません)、さまざまな理由で発生する可能性があります。このような状況でNinjaが正しく機能することができれば幸いです。

敬具、
ロジャー

最も参考になるコメント

フラットパックサンドボックス内にostreeによって処理されわかりませんが、ファイルdeに関連していると思います)。 -複製システム)。 これらのシステムファイルは存在しないとは見なされませんが、「ダーティ」と見なされ、その環境でninjaを実行するたびに完全な再構築がトリガーされます。

ninja -d explainで再構築すると、ファイルがダーティであると表示されます。例:

ninja explain: /usr/include/glib-2.0/gio/gtcpwrapperconnection.h is dirty

全てのコメント14件

bool Cleaner::FileExists(const string& path) {
  string err;
  TimeStamp mtime = disk_interface_->Stat(path, &err);
  if (mtime == -1)
    Error("%s", err.c_str());
  return mtime > 0;  // Treat Stat() errors as "file does not exist".
        ^^^^^^^^^
}

有望な候補のように見えます。 と

  void MarkMissing() {
    mtime_ = 0;
  }

また、 RealDiskInterface::StatDiskInterface::MakeDirs 。 基本的に、タイムスタンプとエラーコードの両方としてmtimeを使用していますが、すべての有効なmtime値が有効なタイムスタンプ(負の値であっても)であることを考えると、これは不可能です。 この仮定は、src /disk_interface.hにも記載されています。

  /// stat() a file, returning the mtime, or 0 if missing and -1 on
  /// other errors.

他のいくつかの場所でも想定されています。 あなたの現在の戦略は安全ではないと思います。特に、アーカイブ形式などで指定されていない場合にゼロがデフォルトになることが多い場合はなおさらです。 st_mtimeとは関係なく、ディレクトリエントリが存在しない場合、基になるstat (2)syscallがENOENTを返すことを考慮してください。 たぶん、 validフラグまたは列挙型(-1および0の場合)とmtimeを含む小さなStat構造を使用できます。 これは、提供することができますoperator<のためにmtime比較し、 operator(bool)またはoperator!の両方が明確に特徴を提供し、問題行動は、ここで観察除去するであろう妥当性チェックのために、。

これは#795の複製です。 誰かが0ではなく1のmtimeを「ファイルが存在しない」ことを意味するようにすることを提案しました:-)

#795の最新のステータスでは、「忍者はmtimeが0のファイルを処理できません」などのメッセージを、混乱して静かにダーティとしてマークする代わりに、簡単に印刷できるようになりました。 それで十分でしょうか?

システムでファイルのmtimeが0になっているのはなぜですか?

mtime of 1は巧妙なハックです! また、すべてのmtimesに1を追加することもできます。
0を使用可能にします。 (mtimesの特定の値は気にしませんが、
これらは、ファイルが変更されると変更される単なるマジッククッキーです。 Windowsの場合
これらは他のランダムな値であり、エポック秒カウンターではありません。)

18:36で火、2016年4月5日には、ニコ・ウェーバー[email protected]書きました:

これは#795https://github.com/ninja-build/ninja/issues/795の複製です。
誰かが0の代わりに1のmtimeを「ファイルはしない」という意味にすることを提案しました
存在" :-)

#795 https://github.com/ninja-build/ninja/issues/795で、最新
ステータスは、「忍者は処理できません」のようなメッセージを簡単に印刷できるようになったことです。
混乱して静かにマークするのではなく、mtimeが0のファイル
汚れた。 それで十分でしょうか?

システムでファイルのmtimeが0になっているのはなぜですか?


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信するか、GitHubで表示してください
https://github.com/ninja-build/ninja/issues/1120#issuecomment -206067067

この特定のインスタンスでmtimeがゼロになる理由は、tarファイルに保存されているTarInfoオブジェクトにmtimeを明示的に設定せずにPython tarfileモジュールを使用するためですzipfileモジュールの類似のインターフェイスの動作とは異なります(新しいファイルを作成するときに予想されるように)。 しかし、他のツールも同様のことを行うのを見てきました。構造のデフォルトはゼロであることが多く、これにより、さまざまな条件下でmtimeがゼロのファイルが必然的に作成されます。

1のmtimeを使用することは確かに「巧妙なハック」であり、ここで問題を確実に回避します。 一方、私が提案したような修正は、それほど手間がかからず、特別な値の必要性をまったく排除し、すべての状況下で堅牢になります。 どちらの方法でも問題ありません。

これをフォローしてくれてありがとう、
ロジャー

しかし、0 mtimeは決して意図的なものではありませんよね? ここでは、エラーが発生するのが最善の方法のようです。

いいえ、意図的ではありません。 しかし、それは偶然に比較的一般的に発生するものです。 エラーアウトは適切ではないと思います。 タイムスタンプが設定されていないソースリリースを作成した場合、それは事実上、忍者では構築できません。 1に設定すると、はるかに優れた戦略になります。

ファイルシステム表現のタイムスタンプをに変換するWindowsコード
忍者タイムスタンプタイプはこちらです:
https://github.com/ninja-build/ninja/blob/master/src/disk_interface.cc#L60

私はこのコードを変更することを提案しています:

https://github.com/ninja-build/ninja/blob/master/src/disk_interface.cc#L193
st.st_mtime +1を返す;

適切に処理しないという犠牲を払ってすべてを解決すると信じています
最大エポックの日付のファイル(ただし、あらゆる種類のy2k38があります)
私たちがその近くにいると、その地域の問題)。

7:56で金、2016年4月8日には、ロジャー・リー[email protected]
書きました:

いいえ、意図的ではありません。 しかし、それは比較的発生するものです
一般的に偶然。 エラーアウトは適切ではないと思います。 もしも
誰もがタイムスタンプが設定されていないソースリリースを作成することはありません。これは事実上の事実です。
忍者では構築できません。 1に設定すると、はるかに優れた戦略になります。


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示してください
https://github.com/ninja-build/ninja/issues/1120#issuecomment -207466847

フラットパックサンドボックス内にostreeによって処理されわかりませんが、ファイルdeに関連していると思います)。 -複製システム)。 これらのシステムファイルは存在しないとは見なされませんが、「ダーティ」と見なされ、その環境でninjaを実行するたびに完全な再構築がトリガーされます。

ninja -d explainで再構築すると、ファイルがダーティであると表示されます。例:

ninja explain: /usr/include/glib-2.0/gio/gtcpwrapperconnection.h is dirty

flatpakの場合、 https: //github.com/flatpak/flatpak/issues/607#issuecomment -287952697のパッチを、これが理解されるまで忍者ビルドに追加します。

#1293でもっと徹底的な修正があると思います

また、Flatpakで使用されているPatrick Griffisのパッチをプルリクエスト#1292として提出しました。これは、十分にテストされていることがわかっている問題の適切な回避策です(ビルドは少なくとも適用されたもので定期的に合格します)。

しかし、セマンティクスが変更され、すべてのmtimeが有効なものになるように、#1293で徹底的に努力しました。これには、0と負のmtimesも含まれますが、コードベースが負のmtimesにどのように耐えられるかはわかりません。 )。 #1293が正しい修正だと思いますが、もちろんもう少し侵襲的な変更であり、それを確認することをお勧めします(deps_log。[cc、h]を変更することになったわけではありませんが、ファイルの存在とmtimesを区別するために、そこで変更が必要です)。 しかし、私は問題なく#1293ブランチを使用して多くのGNOMEモジュールを構築しました。

どちらのルートを選択する場合でも、上流の忍者に修正を加えるとよいでしょう。

ありがとう、私はあなたの#1292をマージしました。 他の場所で述べたように、これは私にとって優れた修正のように見えるので、問題がなければ今のところ#1293を無視します。

そして、修正してくれてありがとう!

ありがとう、私はあなたの#1292をマージしました。 他の場所で述べたように、これは私にとって優れた修正のように見えるので、問題がなければ今のところ#1293を無視します。

心配はいりません。ダウンストリームパッチが必要ないことを嬉しく思います:)

たぶんあなたも#795を閉じることができます

このページは役に立ちましたか?
0 / 5 - 0 評価