Ninja: Les fichiers avec zéro mtime sont traités comme inexistants

Créé le 25 mars 2016  ·  14Commentaires  ·  Source: ninja-build/ninja

Sur un système 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

Cette archive source a été mal compressée, et un seul fichier a un mtime de zéro (c'est-à-dire le début de l'époque 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

La cause:

$ 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

Clairement, le fichier existe. Si je touch /tmp/ome-cmake-superbuild-0.1.0/cmake/GitVersion.cmake pour mettre à jour l'horodatage à l'heure actuelle, alors ninja fonctionne parfaitement. Il semble que Ninja traite les fichiers avec un mtime de zéro comme étant inexistants, ce qui semble incorrect. S'il vous plaît, pourriez-vous envisager de changer ce comportement ? Bien qu'il s'agisse d'un cas inhabituel - les fichiers ne devraient pas avoir un horodatage aussi ancien - cela peut arriver et se produit pour diverses raisons, et ce serait bien si Ninja pouvait fonctionner correctement dans ces circonstances.

Bien à vous,
Roger

Commentaire le plus utile

Je vois quelque chose de similaire ici lors de la construction à l'intérieur d'un bac à sable flatpak , essentiellement tous les fichiers gérés par ostree , ce qui signifie que les fichiers "système" ont un mtime = 0 (je ne sais pas pourquoi ils le font, mais je pense que c'est lié au fichier de -système de duplication). Ces fichiers système ne sont pas considérés comme inexistants mais comme "sales", et une reconstruction complète est déclenchée chaque fois que j'exécute ninja dans cet environnement.

Lors de la reconstruction avec ninja -d explain il est indiqué que les fichiers sont sales, par exemple :

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

Tous les 14 commentaires

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".
        ^^^^^^^^^
}

On dirait un candidat probable. Et

  void MarkMissing() {
    mtime_ = 0;
  }

Aussi RealDiskInterface::Stat et DiskInterface::MakeDirs . Fondamentalement, vous utilisez mtime à la fois comme horodatage _et_ comme code d'erreur, et ce n'est tout simplement pas possible étant donné que toutes les valeurs mtime valides sont également des horodatages valides (même négatifs). Cette hypothèse est même énoncée dans src/disk_interface.h :

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

Il est également supposé dans quelques autres endroits. Je ne pense pas que votre stratégie actuelle soit sûre, en particulier lorsque zéro est souvent la valeur par défaut lorsqu'il n'est pas spécifié dans les formats d'archive, par exemple. Considérez que l'appel système stat (2) sous-jacent renvoie ENOENT lorsqu'une entrée de répertoire n'existe pas, indépendamment de st_mtime. Vous pourriez peut-être utiliser une petite structure Stat contenant un indicateur ou une énumération valid (-1 et 0 cas) plus le mtime . Il pourrait fournir operator< pour la comparaison mtime et operator(bool) ou operator! pour la vérification de validité, ce qui fournirait les deux fonctionnalités sans ambiguïté et supprimerait le comportement problématique observé ici.

C'est une dupe de #795. Quelqu'un a suggéré de laisser un mtime de 1 au lieu de 0 signifier "le fichier n'existe pas" :-)

Sur #795, le dernier statut est qu'il est maintenant facile d'imprimer un message comme "ninja ne peut pas gérer les fichiers avec un mtime de 0" au lieu de les marquer de manière confuse et silencieuse comme sales. Cela vous suffirait-il ?

Pourquoi le mtime du fichier est-il 0 sur votre système ?

mtime de 1 est un hack intelligent ! Pourrait aussi simplement ajouter un à tous les mtimes, à
rendre 0 disponible. (Nous ne nous soucions pas de la valeur spécifique des mtimes,
ils sont juste un cookie magique qui change lorsque le fichier change. Sous Windows
ils sont une autre valeur aléatoire, pas un compteur d'époques-secondes.)

Le mar 5 avril 2016 à 18:36, Nico Weber [email protected] a écrit :

C'est une dupe de # 795 https://github.com/ninja-build/ninja/issues/795.
Quelqu'un a suggéré de laisser un mtime de 1 au lieu de 0 signifier "le fichier ne
exister" :-)

Sur #795 https://github.com/ninja-build/ninja/issues/795 , le dernier
le statut est qu'il est maintenant facile d'imprimer un message comme "ninja ne peut pas gérer
fichiers avec mtime de 0" au lieu de les marquer de manière confuse et silencieuse comme
sale. Cela vous suffirait-il ?

Pourquoi le mtime du fichier est-il 0 sur votre système ?

-
Vous recevez ceci parce que vous êtes abonné à ce fil.
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/ninja-build/ninja/issues/1120#issuecomment -206067067

La raison pour laquelle le mtime est égal à zéro dans cette instance spécifique est l'utilisation du module Python tarfile sans définir explicitement le mtime sur les objets TarInfo enregistrés dans le fichier tar-- la valeur par défaut est zéro à moins qu'elle ne soit définie à la main. Ceci est différent du comportement de l'interface analogue dans le module zipfile , qui utilise par défaut l'heure système actuelle (comme on peut s'y attendre lors de la création d'un nouveau fichier). Mais j'ai vu d'autres outils faire également des choses similaires - zéro est souvent la valeur par défaut dans les structures et cela entraîne inévitablement la création de fichiers avec zéro mtime dans diverses conditions.

L'utilisation d'un mtime de 1 serait en effet un "piratage intelligent" et permettrait certainement de contourner le problème ici. D'un autre côté, un correctif tel que celui que j'ai suggéré ne demanderait pas beaucoup plus d'efforts et supprimerait le besoin de valeurs spéciales, ce qui le rendrait robuste en toutes circonstances. De toute façon, ça me irait.

Merci d'avoir suivi cela,
Roger

Mais le 0 mtime n'est jamais intentionnel, non ? Il semble que l'erreur pourrait être la meilleure façon d'avancer ici.

Ce n'est pas intentionnel, non. Mais c'est quelque chose qui se produit relativement couramment par accident. Je ne pense pas qu'il serait approprié de se tromper; si quelqu'un fait une version source avec un horodatage non défini, c'est de facto impossible à construire avec ninja. Le mettre à 1 serait une stratégie beaucoup plus agréable.

Le code Windows pour convertir l'horodatage de la représentation du système de fichiers en un
Le type d'horodatage Ninja est ici :
https://github.com/ninja-build/ninja/blob/master/src/disk_interface.cc#L60

Je propose de changer ce code :

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

Je crois que cela résoudra tout au prix de notre mauvaise gestion
fichiers avec une date de l'époque maximale (mais nous aurons toutes sortes de y2k38
problèmes dans ce domaine une fois que nous nous en approchons).

Le vendredi 8 avril 2016 à 7h56, Roger Leigh [email protected]
a écrit:

Ce n'est pas intentionnel, non. Mais c'est quelque chose qui se produit relativement
généralement par accident. Je ne pense pas qu'il serait approprié de se tromper; si
quelqu'un fait une version source avec un horodatage non défini, c'est de facto
inconstructible avec ninja. Le mettre à 1 serait une stratégie beaucoup plus agréable.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/ninja-build/ninja/issues/1120#issuecomment -207466847

Je vois quelque chose de similaire ici lors de la construction à l'intérieur d'un bac à sable flatpak , essentiellement tous les fichiers gérés par ostree , ce qui signifie que les fichiers "système" ont un mtime = 0 (je ne sais pas pourquoi ils le font, mais je pense que c'est lié au fichier de -système de duplication). Ces fichiers système ne sont pas considérés comme inexistants mais comme "sales", et une reconstruction complète est déclenchée chaque fois que j'exécute ninja dans cet environnement.

Lors de la reconstruction avec ninja -d explain il est indiqué que les fichiers sont sales, par exemple :

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

Pour flatpak, je vais ajouter le correctif dans https://github.com/flatpak/flatpak/issues/607#issuecomment -287952697 à notre version ninja jusqu'à ce que cela soit résolu.

Je pense avoir un correctif plus complet en #1293

Juste en notant également, j'ai également déposé le patch de Patrick Griffis utilisé dans Flatpak en tant que pull request #1292, ce qui est une bonne solution de contournement pour le problème, que nous savons bien testé (les builds passent régulièrement avec celle appliquée au moins).

Mais j'ai fait des efforts pour le faire à fond dans #1293 afin que la sémantique soit modifiée et que tout mtime soit valide, y compris 0 et les mtimes négatifs qui devraient également être valides (je ne sais pas comment la base de code résiste aux mtimes négatifs, cependant ). Bien que je pense que #1293 est le correctif correct, il s'agit bien sûr d'un changement un peu plus invasif et il serait bon de le revoir (je n'ai pas fini par modifier deps_log.[cc,h], je ne sais pas si un une modification est nécessaire ici pour faire la distinction entre l'existence du fichier et mtimes). J'ai cependant construit beaucoup de modules GNOME en utilisant la branche #1293 sans problème.

Quelle que soit la route empruntée, ce serait bien d'avoir une solution dans le ninja en amont pour cela.

Merci, j'ai fusionné votre #1292. Comme dit ailleurs, cela ressemble à la solution supérieure pour moi, donc j'ignorerai 1293 pour l'instant si cela vous convient.

Et merci beaucoup pour la correction !

Merci, j'ai fusionné votre #1292. Comme dit ailleurs, cela ressemble à la solution supérieure pour moi, donc j'ignorerai 1293 pour l'instant si cela vous convient.

Pas de soucis, je suis juste content de ne pas avoir besoin d'un patch en aval :)

Peut-être que vous pouvez aussi fermer #795

Cette page vous a été utile?
0 / 5 - 0 notes