Ninja: Arquivos com zero mtime são tratados como inexistentes

Criado em 25 mar. 2016  ·  14Comentários  ·  Fonte: ninja-build/ninja

Em um sistema 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

Este arquivo de origem foi compactado incorretamente e um único arquivo tem mtime zero (ou seja, início da época 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

A causa:

$ 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

Claramente, o arquivo existe. Se eu touch /tmp/ome-cmake-superbuild-0.1.0/cmake/GitVersion.cmake atualizar o carimbo de data / hora para a hora atual, ninja funcionará perfeitamente. Parece que o Ninja está tratando os arquivos com tempo zero como inexistentes, o que parece incorreto. Por favor, você poderia considerar mudar esse comportamento? Embora este seja um caso incomum - os arquivos não deveriam ter um carimbo de data / hora tão antigo - isso pode acontecer e acontece por vários motivos, e seria bom se o Ninja pudesse funcionar corretamente nessas circunstâncias.

Atenciosamente,
Roger

Comentários muito úteis

Estou vendo algo semelhante aqui ao construir dentro de uma sandbox flatpak , basicamente todos os arquivos manipulados por ostree , o que significa que os arquivos de "sistema" têm um mtime = 0 (não sei por que eles fazem isso, mas acho que está relacionado ao arquivo de -sistema de duplicação). Esses arquivos de sistema não são considerados inexistentes, mas sim "sujos", e a reconstrução completa é acionada toda vez que estou executando o ninja naquele env.

Ao reconstruir com ninja -d explain diz que os arquivos estão sujos, por exemplo:

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

Todos 14 comentários

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

Parece um candidato provável. E

  void MarkMissing() {
    mtime_ = 0;
  }

Também RealDiskInterface::Stat e DiskInterface::MakeDirs . Fundamentalmente, você está usando mtime como um carimbo de data / hora _e_ um código de erro, e isso simplesmente não é possível, visto que todos os valores de mtime válidos também são carimbos de data / hora válidos (mesmo os negativos). Essa suposição é mesmo declarada em src / disk_interface.h:

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

É assumido em alguns outros lugares também. Não acho que sua estratégia atual seja segura, especialmente quando zero é frequentemente o padrão quando não especificado em, por exemplo, formatos de arquivo. Considere que o stat (2) syscall subjacente retorna ENOENT quando uma entrada de diretório não existe, independentemente de st_mtime. Talvez você pudesse usar uma pequena estrutura Stat contendo um sinalizador valid ou enum (-1 e 0 casos) mais o mtime . Ele poderia fornecer operator< para mtime comparação e operator(bool) ou operator! para verificação de validade, o que forneceria ambos os recursos inequivocamente e removeria o comportamento problemático observado aqui.

Este é um dupe de # 795. Alguém sugeriu que um mtime de 1 em vez de 0 significasse "o arquivo não existe" :-)

No # 795, o status mais recente é que agora é fácil imprimir uma mensagem como "o ninja não pode lidar com arquivos com mtime de 0" em vez de marcá-los como sujos de maneira confusa e silenciosa. Isso seria bom o suficiente para você?

Por que o mtime do arquivo é 0 em seu sistema?

mtime of 1 é um hack inteligente! Também poderia apenas adicionar um a todos os mtimes, para
disponibilizar 0. (Não nos importamos com o valor específico dos mtimes,
eles são apenas um cookie mágico que muda quando o arquivo muda. No Windows
eles são algum outro valor aleatório, não um contador de segundos de época.)

Na terça-feira, 5 de abril de 2016 às 18:36, Nico Weber [email protected] escreveu:

Este é um dupe de # 795 https://github.com/ninja-build/ninja/issues/795.
Alguém sugeriu que um mtime de 1 em vez de 0 significasse "arquivo não
existir" :-)

Em # 795 https://github.com/ninja-build/ninja/issues/795 , o mais recente
status é que agora é fácil imprimir uma mensagem como "o ninja não consegue lidar
arquivos com mtime de 0 "em vez de marcá-los de forma confusa e silenciosa como
sujo. Isso seria bom o suficiente para você?

Por que o mtime do arquivo é 0 em seu sistema?

-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/ninja-build/ninja/issues/1120#issuecomment -206067067

A razão para o mtime ser zero nesta instância específica é usar o módulo Python tarfile sem definir explicitamente mtime nos objetos TarInfo sendo salvos no arquivo tar-- o padrão é zero, a menos que seja definido manualmente. Isso é diferente do comportamento da interface análoga no módulo zipfile , que é padronizado para a hora atual do sistema (como pode ser esperado ao criar um novo arquivo). Mas eu vi outras ferramentas também fazerem coisas semelhantes - zero geralmente é o padrão em estruturas e isso inevitavelmente resulta em arquivos com zero mtime sendo criados sob várias condições.

Usar um mtime de 1 seria de fato um "hack inteligente" e certamente resolveria o problema aqui. Por outro lado, uma correção como a que sugeri não exigiria muito mais esforço e removeria a necessidade de quaisquer valores especiais, tornando-a robusta em todas as circunstâncias. De qualquer maneira, estaria bom para mim.

Obrigado por acompanhar isso,
Roger

Mas o 0 mtime nunca é intencional, certo? Parece que errar pode ser a melhor maneira de avançar aqui.

Não é intencional, não. Mas é algo que ocorre com relativa frequência por acidente. Não acho que errar seria apropriado; se alguém fizer uma versão do código-fonte com um carimbo de data / hora não definido, isso é de fato impossível de construir com o ninja. Definir como 1 seria uma estratégia muito mais agradável.

O código do Windows para converter o registro de data e hora da representação do sistema de arquivos em um
O tipo Ninja TimeStamp está aqui:
https://github.com/ninja-build/ninja/blob/master/src/disk_interface.cc#L60

Estou propondo mudar este código:

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

Eu acredito que vai resolver tudo ao custo de não lidarmos adequadamente
arquivos com uma data de época máxima (mas teremos todos os tipos de y2k38
problemas nessa área quando estivermos perto disso).

Na sexta-feira, 8 de abril de 2016 às 7h56, Roger Leigh [email protected]
escreveu:

Não é intencional, não. Mas _é_ algo que ocorre relativamente
comumente por acidente. Não acho que errar seria apropriado; E se
qualquer pessoa já fez uma versão do código-fonte com um carimbo de data / hora não definido, isso é de fato
inacreditável com ninja. Definir como 1 seria uma estratégia muito mais agradável.

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/ninja-build/ninja/issues/1120#issuecomment -207466847

Estou vendo algo semelhante aqui ao construir dentro de uma sandbox flatpak , basicamente todos os arquivos manipulados por ostree , o que significa que os arquivos de "sistema" têm um mtime = 0 (não sei por que eles fazem isso, mas acho que está relacionado ao arquivo de -sistema de duplicação). Esses arquivos de sistema não são considerados inexistentes, mas sim "sujos", e a reconstrução completa é acionada toda vez que estou executando o ninja naquele env.

Ao reconstruir com ninja -d explain diz que os arquivos estão sujos, por exemplo:

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

Para flatpak, vou adicionar o patch em https://github.com/flatpak/flatpak/issues/607#issuecomment -287952697 à nossa construção ninja até que isso seja descoberto.

Acho que tenho uma correção mais completa em # 1293

Apenas observando também, eu também arquivei o patch de Patrick Griffis usado no Flatpak como solicitação de pull # 1292, que é uma boa solução alternativa para o problema, que sabemos que foi bem testado (compilações passam regularmente com aquele aplicado, pelo menos).

Mas eu me esforcei para fazê-lo completamente em # 1293 para que a semântica fosse alterada e qualquer mtime seja válido, incluindo 0 e mtimes negativos, que também devem ser válidos (não tenho certeza de como a base de código resiste a mtimes negativos, embora ) Embora eu ache que o nº 1293 é a correção correta, é claro que é uma alteração um pouco mais invasiva e seria bom revisar isso (eu não acabei modificando deps_log. [Cc, h], não tenho certeza se um a mudança é necessária lá para distinguir entre a existência do arquivo e mtimes). No entanto, construí muitos módulos GNOME usando o branch # 1293 sem problemas.

Qualquer que seja a rota escolhida, seria bom ter alguma correção no ninja upstream para isso.

Obrigado, eu mesclei seu # 1292. Como disse em outro lugar, essa parece ser a solução superior para mim, então vou ignorar o # 1293 por enquanto se estiver tudo bem para você.

E muito obrigado pela correção!

Obrigado, eu mesclei seu # 1292. Como disse em outro lugar, essa parece ser a solução superior para mim, então vou ignorar o # 1293 por enquanto se estiver tudo bem para você.

Não se preocupe, estou feliz por não precisar de um patch downstream :)

Talvez você também possa fechar # 795

Esta página foi útil?
0 / 5 - 0 avaliações