Может ли 'make' проверить, отличается ли mtime зависимости между прогонами, а не только, если она новее целевой? - PullRequest
2 голосов
/ 10 ноября 2009

Если foo_user.cpp зависит от foo.h, то создается foo_user.cpp, а затем время модификации foo.h устанавливается в дальнейшем, make не будет перестраивать foo_user.cpp (потому что foo.cpp 'новее «). Я бы предпочел, чтобы make записывал время изменения зависимостей и если они вообще изменились (более новые или более старые), чтобы считать цели этой зависимости устаревшими. Может ли GNU сделать это? Если нет, есть ли легкая альтернатива?

В случае, если вам интересно, как возникает такая ситуация: foo.h находится в папке с символическими ссылками. Символическая ссылка может указывать на папку foolib-1.0, папку foolib-2.0 и т. Д. Если символическая ссылка указывает на другую версию библиотеки, даже на более старую версию, файл foo_user.cpp должен быть перестроен. Если я просто указываю symlinkfolder / foo.h как зависимость foo_user.cpp, make обращает внимание только на временную метку foo.h, а не на временную метку каталога symlink'd, через которую осуществляется доступ к foo.h. Я не могу добавить символическую ссылку в качестве зависимости, потому что правило make генерируется компилятором (GCC имеет специальный флаг, который при его получении выводит правило make для всех заголовков, от которых зависит исходный файл).

Ответы [ 4 ]

3 голосов
/ 10 ноября 2009

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

x.o: a.h b.h    
x.o: c.h    
x.o: d.h

Но, сказав это, кажется вероятным, что make будет определять цель символической ссылки, а не саму символическую ссылку, так что, возможно, не DTRT. Я полагаю, вы можете просто прикоснуться к файлу где-нибудь, когда создадите символическую ссылку, но я также предполагаю, что вы уже подумали об этом ...

У вас может быть правило, которое запускает ls -id link/. > test, в котором номер индекса целевого каталога ссылки будет помещен в test. Тогда вы могли бы cmp test save, где save от последнего запуска. Тогда вы могли бы сделать это правило make make clean && make target, если они отличаются.

targetwrapper: 
    ls -id link/. > test
    cmp test save || make clean
    make realtarget
    cp test save

clean:
    echo cleaned

realtarget:
    echo made
2 голосов
/ 10 ноября 2009

Нет, Make не поддерживает это. Вы можете рассмотреть возможность использования другой системы сборки, такой как SCons , которая не полагается исключительно на временную метку, но фактически вычисляет хеш MD5 исходных файлов и основывает свои решения на хешах.

Из "Что делает SCons лучше?" на своем веб-сайте:

  • Надежное обнаружение изменений в сборке с использованием сигнатур MD5; дополнительная, настраиваемая поддержка традиционных временных меток.
1 голос
/ 10 ноября 2009

Хотя make не поддерживает его из коробки, вы можете запрограммировать его.

include more_deps

ifneq ($(MAKE_RESTARTS),)

more_deps:
  if (foolink.old differs from what foolink points to) ; then \
    readlink foolink > foolink.old ; \
    echo "foo_user: foolink_trigger" > more_deps ; \
    touch foolink_trigger ; \
  else \
    echo "" > more_deps ;\
  fi

endif

foo_user: foo_user.cpp
  g++ $^ -o $@

Здесь вы включаете make-файл more_deps, который иногда будет включать зависимость от триггера символической ссылки. Триггер - это специальный промежуточный файл, вся значимая информация которого содержит его метку времени. Когда символическая ссылка изменяется, временная метка триггера обновляется до текущего времени (см. touch), что делает foo_user устаревшим, и он перестраивается.

include и MAKE_RESTARTS необходимы для перезапуска make после вычисления зависимости, описанной выше. Если включаемый make-файл сам является целью, цель считается восстановленной, перестраивается, а затем перезапускается и перечитывает make-файл. Но когда он читает make-файл во второй раз, он не видит more_deps в качестве цели, потому что переменная MAKE_RESTARTS расширяется до непустой строки.

На самом деле строка if может звучать так:

more_deps:
  if (any condition you want with $(VARIABLES) possible!) ; then \
     update a file that holds the previous state ;\ 
     ...
0 голосов
/ 10 ноября 2009

Через какой процесс вы меняете символическую ссылку? Вы можете добавить к сценарию действие типа make clean, которое изменяет символическую ссылку.

Вы также можете создать «рабочую папку заголовков», позволяющую make copy копировать файлы заголовков, где скопированные файлы заголовков зависят от их оригинала и символической ссылки. Зависимости, сгенерированные GCC, учитывают только рабочие заголовки и не конфликтуют с вашей copy headers into the working folder частью вашего Makefile.

...