В системе 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 мог правильно работать в этих обстоятельствах.
С уважением,
Роджер
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
Самый полезный комментарий
Я вижу здесь нечто подобное при создании внутри песочницы Flatpak , в основном все файлы, обрабатываемые ostree , что означает, что "системные" файлы имеют mtime = 0 (не уверен, почему они это делают, но я думаю, что это связано с файлом de -дупликационная система). Эти системные файлы не считаются несуществующими, а считаются «грязными», и полная перестройка запускается каждый раз, когда я запускаю ninja в этом окружении.
При перестроении с
ninja -d explain
он говорит, что файлы грязные, например: