заставить GNU-make использовать время модификации цели символьной ссылки, а не время модификации источника - PullRequest
0 голосов
/ 14 сентября 2018

У меня проблема со временем модификации в GNU make 3.81.

Мой Makefile использует данные, смонтированные с удаленного сервера, который по какой-то неизвестной мне причине установил Время модификации файлов, установленных вдалекое будущее (в следующее столетие).

Сначала Makefile создает символическую ссылку на удаленный файл «из будущего» в локальном каталоге, а затем на основе этого файла запускает несколько сценариев, которые все генерируют некоторый выводфайлы.

Теперь, когда я хочу перезапустить «сделать все» после того, как он был прерван, чтобы получить все мои выходные файлы, он не будет перезапущен с последним сгенерированным выходным файлом (скажем, из сценария № 3).), но вместо этого он восстанавливает все с самого начала, так как он замечает, что первый файл (тот, в котором я символически связал файл «из будущего») является более новым.

Есть ли опция, чтобы сказать make, чтобы взятьвремя модификации самой символьной ссылки, а не время модификации цели символической ссылки?

Пример

Вот минимальный рабочий пример, восстанавливающий проблему:

Настройка папки и файлов:

mkdir symlinkmake
cd symlinkmake
echo $PWD > futurefile.txt
# set file modification time to the future
touch -t 212111111111 futurefile.txt

Содержимое файла Makefile:

all: symlink.txt first_output.txt second_output.txt

symlink.txt:
    ln -s futurefile.txt symlink.txt

first_output.txt: symlink.txt
    cut -f1 -d"/" symlink.txt > first_output.txt

second_output.txt: first_output.txt
    wc first_output.txt > second_output.txt

Теперь запустите make all и удалите второй выходной файл.Затем перезапустите make.Поскольку первый выходной файл уже существует, необходимо создать только второй файл.Но поскольку futurefile.txt новее, чем любой другой файл, будет также сгенерирован первый выходной файл:

make all
rm second_output.txt
make all

На моей машине вывод выглядит так:

$ ls
Makefile        futurefile.txt  symlink.txt
$ make all
make: Warning: File `symlink.txt' has modification time 3.3e+09 s in the future
cut -f1 -d"/" symlink.txt > first_output.txt
wc first_output.txt > second_output.txt
make: warning:  Clock skew detected.  Your build may be incomplete.
$ rm second_output.txt
$ make all
make: Warning: File `symlink.txt' has modification time 3.3e+09 s in the future
cut -f1 -d"/" symlink.txt > first_output.txt
wc first_output.txt > second_output.txt
make: warning:  Clock skew detected.  Your build may be incomplete.

1 Ответ

0 голосов
/ 14 сентября 2018

Существует опция --check-symlink-times make , но:

В системах, поддерживающих символические ссылки, эта опция заставляет make учитывать временные метки на любых символических ссылках в дополнение кметка времени в файле, на который ссылаются эти ссылки.Когда эта опция предоставлена, самая последняя временная метка среди файла и символических ссылок берется как время модификации для этого целевого файла.

Это не то, что вам нужно, это учитывать только временную метку ссылки.Поскольку вы не можете решить проблему с датой и временем, я могу представить только одно из двух решений

  1. предварительные условия только для заказа (ООП):

    .PHONY: all
    
    all: first_output.txt second_output.txt | symlink.txt
    
    symlink.txt:
        ln -s futurefile.txt $@
    
    first_output.txt: | symlink.txt
        cut -f1 -d"/" $| > $@
    
    second_output.txt: first_output.txt
        wc $< > $@
    

    symlink.txt будучи создателем ООП, будет учитывать только его существование, а не метку времени.Другими словами, make создаст его и (пере) построит все цели, которые зависят от него, только если он отсутствует.

    Примечание: я также использовал автоматические переменные везде, где этобыло возможноОни удобны, менее подвержены ошибкам и часто позволяют факторизовать правила.

    Недостаток : это скорее быстрый и грязный взлом, чем реальное решение.В самом деле, если файл, на который ссылается ссылка, изменится, остальные ваши цели не будут перестроены:

    $ ls -al
    Sep 14 14:55 Makefile
    Dec  1  2018 futurefile.txt
    $ make
    ln -s futurefile.txt symlink.txt
    cut -f1 -d"/" symlink.txt > first_output.txt
    wc first_output.txt > second_output.txt
    $ ls -al
    Sep 14 14:55 Makefile
    Sep 14 15:05 first_output.txt
    Dec  1  2018 futurefile.txt
    Sep 14 15:05 second_output.txt
    Sep 14 15:05 symlink.txt -> futurefile.txt
    $ make
    make: Warning: File 'symlink.txt' has modification time 6688452 s in the future
    make: Nothing to be done for 'all'.
    make: warning:  Clock skew detected.  Your build may be incomplete.
    $ touch --date=2018-12-02 futurefile.txt
    $ ls -al futurefile.txt
    $ make
    make: Warning: File 'symlink.txt' has modification time 6774852 s in the future
    make: Nothing to be done for 'all'.
    make: warning:  Clock skew detected.  Your build may be incomplete.
    
  2. Чтобы уменьшить недостаток первого решения, выпри создании целей вам придется заменить дату / время вашего локального хоста на дату / время вашего удаленного сервера.Случайно, команда touch имеет приятную опцию --reference, которая заставляет временную метку файла быть такой же, как у другого файла:

    .PHONY: all
    
    all: first_output.txt second_output.txt
    
    first_output.txt: futurefile.txt
        cut -f1 -d"/" $< > $@
        touch --reference=$< $@
    
    second_output.txt: first_output.txt
       wc $< > $@
       touch --reference=$< $@
    

    Откат : вместо одной символическойссылка, у вас будет два файла (first_output.txt и second_output.txt) со временем в будущем:

    $ ls -al
    Sep 14 14:55 Makefile
    Dec  1  2018 futurefile.txt
    $ make
    make: Warning: File 'futurefile.txt' has modification time 6688320 s in the future
    cut -f1 -d"/" futurefile.txt > first_output.txt
    touch --reference=futurefile.txt first_output.txt
    wc first_output.txt > second_output.txt
    touch --reference=first_output.txt second_output.txt
    make: warning:  Clock skew detected.  Your build may be incomplete.
    $ ls -al
    Sep 14 14:55 Makefile
    Dec  1  2018 first_output.txt
    Dec  1  2018 futurefile.txt
    Dec  1  2018 second_output.txt
    $ make
    make: Warning: File 'first_output.txt' has modification time 6688320 s in the future
    make: Nothing to be done for 'all'.
    make: warning:  Clock skew detected.  Your build may be incomplete.
    $ touch --date=2018-12-02 futurefile.txt
    $ ls -al futurefile.txt
    $ make
    make: Warning: File 'first_output.txt' has modification time 6688320 s in the future
    cut -f1 -d"/" futurefile.txt > first_output.txt
    touch --reference=futurefile.txt first_output.txt
    wc first_output.txt > second_output.txt
    touch --reference=first_output.txt second_output.txt
    make: warning:  Clock skew detected.  Your build may be incomplete.
    
...