Создайте make target, если содержимое каталога изменилось - PullRequest
0 голосов
/ 05 февраля 2019

Мне нужен Makefile, который позволяет мне ввести make foo-program и, если какой-либо файл foo-program/**/*.hs изменился с момента последней сборки, построить цель (вывод в foo-program/.stack-work).

Вот мой каталогtree:

project/
|-bar-other-program/
  |-.stack-work/ # Generated output goes here
  |-src/
    |-BarOtherProgram.hs
  |-test/
    |-Tests.hs
|-foo-program/
  |-.stack-work/ # Generated output goes here
  |-src/
    |-FooProgram.hs
  |-test/
    |-Tests.hs
|-notes/ # non-source, so no Make target for this

Вот что у меня есть:

# evaluates to 'bar-other-program foo-program'
PROGS := $(shell find * -type f -name '*.hs' | cut -d'/' -f1 | uniq)

.SECONDEXPANSION:
$(PROGS): $$(wildcard $$@/src/*.hs) $$(wildcard $$@/test/*.hs)
    # do-build $@

Когда я запускаю make foo-program, изменился ли источник или нет, я получаю:

make: Nothing to be done for 'foo-program'

ОБНОВЛЕНИЕ: Мой последний (не абстрагированный) Makefile можно найти на GitHub .Обратите внимание, что мое решение приняло другой оборот, чем я рассчитывал, когда писал этот вопрос.Просмотр этого Makefile также может прояснить мою первоначальную цель.

1 Ответ

0 голосов
/ 05 февраля 2019

Я не совсем уверен относительно цели cut -d'/'.

Но если вы просто хотите получить список *.hs файлов в текущем каталоге (рекурсивно найден), а затем создать цель /исполняемый файл в зависимости от того, изменились ли они, вы можете сделать что-то вроде этого:

PROGS = $(subst ./,,$(shell find . -type f -name '*.hs'))
DEPS = $(addprefix stackwork/,$(addsuffix .dep,$(basename $(PROGS))))
DIRS = $(dir $(DEPS))

.PHONY: foo-program
foo-program: $(DEPS) $(DIRS)

stackwork/%.dep: %.hs | $(DIRS)
    @echo making $@
    @touch $@

$(DIRS):
    @echo creating dir $@
    @mkdir -p $@

clean:
    @rm -rf $(DEPS) $(DIRS)

Где:

  • PROGS - ваш список .hs файлов
  • DEPS - это список сгенерированных файлов зависимостей (пусто, но будут использоваться отметки даты)
  • DIRS - это список выходных каталогов, которые необходимо создать (я думаю, их нетпо умолчанию, поскольку они являются выходными папками?)
  • foo-program - это правило, которое вы можете вызвать (PHONY, потому что на данный момент он не создает настоящий файл)
  • %.dep: %.hs - этоправило, как генерировать файл .dep (это может быть .o .obj или любой другой тип файла), которое зависит от его эквивалентного файла .hs.
  • $(DIRS): это правило для создания выходных каталогов, если это необходимо.

Так что, если файлы .dep не существуют, все файлы .hs будутбыть "скомпилированным".Если все файлы .dep существуют и актуальны, то ничего не будет скомпилировано.Если один или несколько файлов устарели, будут созданы только эти файлы.Вот результат запуска этого на моем ПК с несколькими тестовыми файлами:

admin@osboxes:~/sandbox$ make
    creating dir stackwork/
    creating dir stackwork/test/
    creating dir stackwork/test/test2/
    making stackwork/file.dep
    making stackwork/test/file.dep
    making stackwork/test/test2/file2.dep

admin@osboxes:~/sandbox$ make
    make: Nothing to be done for 'foo-program'.

admin@osboxes:~/sandbox$ touch test/file.hs      
admin@osboxes:~/sandbox$ make
    making stackwork/test/file.dep

admin@osboxes:~/sandbox$ make
    make: Nothing to be done for 'foo-program'.
...