Ninja: Файлы с нулевым mtime считаются несуществующими

Созданный на 25 мар. 2016  ·  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 мог правильно работать в этих обстоятельствах.

С уважением,
Роджер

Самый полезный комментарий

Я вижу здесь нечто подобное при создании внутри песочницы Flatpak , в основном все файлы, обрабатываемые ostree , что означает, что "системные" файлы имеют mtime = 0 (не уверен, почему они это делают, но я думаю, что это связано с файлом 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::Stat и DiskInterface::MakeDirs . По сути, вы используете mtime как метку времени и как код ошибки, и это просто невозможно, учитывая, что все допустимые значения mtime также являются допустимыми метками времени (даже отрицательными). Это предположение даже указано в src / disk_interface.h:

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

Это предполагается и в некоторых других местах. Я не думаю, что ваша текущая стратегия безопасна, особенно когда по умолчанию часто используется ноль, если он не указан, например, в форматах архивов. Учтите, что базовый системный вызов stat (2) возвращает ENOENT когда запись в каталоге не существует, независимо от st_mtime. Возможно, вы могли бы использовать небольшую структуру Stat содержащую флаг valid или перечисление (случаи -1 и 0) плюс mtime . Он может предоставить operator< для сравнения mtime и operator(bool) или operator! для проверки действительности, что однозначно предоставит обе функции и устранит проблемное поведение, наблюдаемое здесь.

Это обман # 795. Кто-то предложил, чтобы mtime равным 1 вместо 0 означало, что "файл не существует" :-)

На # 795 последний статус состоит в том, что теперь легко напечатать сообщение типа «ниндзя не может обрабатывать файлы с mtime, равным 0», вместо того, чтобы сбивать с толку и молча пометить их как грязные. Было бы вам этого достаточно?

Почему в вашей системе mtime 0 файла?

mtime of 1 - умный взлом! Можно также просто добавить один ко всем mtimes, чтобы
сделать 0 доступным. (Нас не волнует конкретная ценность mtimes,
они просто волшебные куки, которые меняются при изменении файла. В Windows
это какое-то другое случайное значение, а не счетчик эпох и секунд.)

Во вторник, 5 апреля 2016 г., в 18:36 Нико Вебер [email protected] написал:

Это обман # 795 https://github.com/ninja-build/ninja/issues/795.
Кто-то предложил поставить mtime равным 1 вместо 0, что означает, что файл не
существовать" :-)

На # 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 равняется нулю в этом конкретном случае, заключается в использовании модуля Python tarfile без явной установки mtime TarInfo объектов zipfile , в котором по умолчанию используется текущее системное время (как можно было ожидать при создании нового файла). Но я видел, что другие инструменты также делают аналогичные вещи - ноль часто является значением по умолчанию в структурах, и это неизбежно приводит к созданию файлов с нулевым mtime при различных условиях.

Использование mtime, равного 1, действительно было бы "хитрым приемом" и, безусловно, помогло бы обойти проблему здесь. С другой стороны, исправление, подобное тому, что я предлагал, потребует не намного больше усилий и вообще устранит необходимость в каких-либо специальных значениях, что сделает его надежным при любых обстоятельствах. В любом случае меня устроит.

Спасибо, что следили за этим,
Роджер

Но время 0 никогда не бывает преднамеренным, верно? Похоже, что ошибка может быть лучшим способом продвижения вперед.

Это не намеренно, нет. Но это то, что относительно часто случается случайно. Я не думаю, что ошибка будет уместна; если кто-нибудь когда-нибудь сделает исходный релиз с неустановленной меткой времени, это де-факто невозможно создать с помощью Ninja. Установка его на 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
проблемы в этой области, как только мы приблизимся к ней).

Пт, 8 апреля 2016 г., 7:56, Роджер Ли [email protected]
написал:

Это не намеренно, нет. Но это то, что происходит относительно
обычно случайно. Я не думаю, что ошибка будет уместна; если
кто-либо когда-либо выпускает исходный код с неустановленной меткой времени, это де-факто
невозможно построить с помощью ниндзя. Установка его на 1 была бы гораздо более хорошей стратегией.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/ninja-build/ninja/issues/1120#issuecomment -207466847

Я вижу здесь нечто подобное при создании внутри песочницы Flatpak , в основном все файлы, обрабатываемые ostree , что означает, что "системные" файлы имеют mtime = 0 (не уверен, почему они это делают, но я думаю, что это связано с файлом 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, в качестве запроса на вытягивание № 1292, что является хорошим обходным путем для проблемы, которая, как мы знаем, хорошо протестирована (сборки регулярно проходят, по крайней мере, с этим примененным).

Но я приложил некоторые усилия, чтобы сделать это тщательно в # 1293, чтобы семантика была изменена, и любое mtime было допустимым, включая 0 и отрицательное mtimes, которое также должно быть действительным (не уверен, как кодовая база выдерживает отрицательное mtimes, хотя ). Хотя я думаю, что # 1293 - правильное исправление, это, конечно, немного более инвазивное изменение, и было бы неплохо его просмотреть (я не стал изменять deps_log. [Cc, h], я не уверен, что требуется изменение, чтобы различать существование файла и время). Однако я без проблем построил множество модулей GNOME, используя ветку # 1293.

Какой бы маршрут ни был выбран, было бы неплохо исправить это в восходящем ниндзя.

Спасибо, слил ваш # 1292. Как сказано в другом месте, мне кажется, что это лучшее исправление, поэтому я пока проигнорирую # 1293, если вас устраивает.

И большое спасибо за исправление!

Спасибо, слил ваш # 1292. Как сказано в другом месте, мне кажется, что это лучшее исправление, поэтому я пока проигнорирую # 1293, если вас устраивает.

Не волнуйтесь, я просто счастлив, что мне не нужен нижестоящий патч :)

Может быть, ты тоже сможешь закрыть # 795

Была ли эта страница полезной?
0 / 5 - 0 рейтинги