Одним из параметров ключа компиляции является хеш git каммита: REPO_REV=0x$(shell git rev-parse --short=8 HEAD) И естественно make не знает, что этот параметр изменился. Как можно заставить make в этом случае пересобрать проект?
-
это строка из мэйкфайла и вы время от времени её меняете? – aleksandr barakin Jan 11 '18 at 05:59
-
Нет. Сама строка естественно не меняется. Меняется результат 0x$(shell git rev-parse --short=8 HEAD), т.е. REPO_REV, который включен в CFLAGS. И хоть он и меняется, make не считает что нужно пересобирать проект – Aleksandr Safronov Jan 11 '18 at 06:09
-
Мы при сборке проектов используем полную очистку, затем полную сборку. Это гарантирует чистоту сборки. Несколько раз сталкивались с ошибками сборки, поэтому были принята такая крайняя мера. Полностью проект для всех платформ в нашем случае собирается 15-20 минут, для справки. Это не ответ, просто вариант, возможно он вам подойдет. – wirtwelt Jan 11 '18 at 06:13
-
У нас полная компиляция занимает меньше времени ~2 минуты, но и это много. Хотелось бы более быстрый вариант. Спасибо! – Aleksandr Safronov Jan 11 '18 at 06:23
1 Answers
Как можно заставить make в этом случае пересобрать проект?
если под «пересборкой проекта» вы подразумеваете выполнение каких-то дополнительных целей (например,
clean,distcleanи т.п.), то требуется подмена целей. это, в принципе, возможно, но довольно «хрупко» и совсем «неуниверсально».с моей точки зрения, такую обработку лучше делать на более высоком уровне:
- если вы запускаете программу make вручную, то, конечно, знаете о том, что
headвнутри репозитория изменился, и требуется указать дополнительную цель; - если запуск программы make у вас автоматизирован, то проверять вывод команды
git rev-parse HEADнадо перед её вызовом, и, если он изменился, вызывать программу с дополнительной целью.
- если вы запускаете программу make вручную, то, конечно, знаете о том, что
если под «пересборкой проекта» вы подразумеваете то, что всего лишь требуется обновить некий набор целей, то можно поступить так:
предыдущий вывод команды
git rev-parse HEADсохранять в каком-нибудь временном файле, при вызове программы make сравнивать содержимое этого файла с текущим выводом той же команды, и, если они не совпадают, перезаписывать файл новым содержимым, а для нужных вам целей указать этот временный файл в качестве пререквизита.проиллюстрирую на примере. допустим, у вас сейчас вот такой примитивный
makefileс двумя реальными целями —file1иfile2:all: file1 file2 file1: touch $@ file2: touch $@добавим в начало получение: а) текущего значения
headв переменнуюrepo_revи б) сохранённого во временном файле с именем, например,rev.save, в переменнуюrev_save:repo_rev = 0x$(shell git rev-parse --short=8 HEAD) rev_save = 0x$(shell cat rev.save 2>/dev/null)а также обновление содержимого файла
rev.saveв случае, если содержимое переменныхrepo_revиrev_saveне совпадает:ifneq ($(repo_rev),$(rev_save)) $(shell echo $(repo_rev) > rev.save) endifзатем после умолчальной цели (в данном случае —
all) добавим файл-пререквизитrev.saveко всем целям, которые надо будет обновить после обновления этого файла:file1 file2: rev.saveитоговый файл примет такой вид:
repo_rev = 0x$(shell git rev-parse --short=8 HEAD) rev_save = 0x$(shell cat rev.save 2>/dev/null) ifneq ($(repo_rev),$(rev_save)) $(shell echo $(repo_rev) > rev.save) endif all: file1 file2 file1 file2: rev.save file1: touch $@ file2: touch $@теперь цели
file1иfile2(при вызвове программы make) будут обновлены и в том случае, если командаgit rev-parse HEADвернёт новое значение.
- 68,117
-
Спасибо за развёрнутый ответ! Именно с файлом я первоначально и сделал. Но сейчас просто поставил после линкера тач файлов. Файлы "маленькие" компилятся быстро. Единственное этот вариант не работает нормально при вызове запуске компиляции с ключом -jN (N потоков). Зависимости all начинают выполняться параллельно. И тач файлов не отрабатывает! – Aleksandr Safronov Jan 12 '18 at 04:20
-
-
- поставил после линкера тач файлов — не улавливаю смысл. 2. этот вариант не работает — первый и второй вариант — точно работают. 3. Ваш вариант не работает с ключом в несколько потоков — третий из вариантов? в чём именно заключается неработоспособность? приведите, пожалуйста, минимальный самодостаточный пример, который «не работает»
– aleksandr barakin Jan 12 '18 at 11:24