2014-11-26 3 views
3

Say У меня есть Makefile, в котором я хочу, чтобы скопировать несколько файлов из одного места в другое, например:Копирование кучу файлов с GNU сделать

  • include/mylib/mylib.h к dist/include/mylib/mylib.h
  • include/mylib/platform/linux/platform.h в dist/include/mylib/platform.h

Это часть правила "установить". Что приходит на ум что-то в этом роде:

EXTRA_INSTALL += include/mylib/mylib.h=dist/include/mylib/mylib.h 
EXTRA_INSTALL += include/mylib/platform/linux/platform.h=dist/include/mylib/platform.h 

# All other dependecies (objects, .so, etc.) go through `$(TARGET)` 
install: $(TARGET) $(EXTRA_INSTALL) 

$(EXTRA_INSTALL): 
    @cp $(firstword $(subst =, ,[email protected])) $(lastword $(subst =, ,[email protected])) 

.PHONY: install $(EXTRA_INSTALL) 

Я думаю, что это своего рода хак, но я не мог придумать правильный способ сделать это. Так есть лучший способ добиться того же? Обратите внимание, что нет видимой связи между входным именем файла и выходным, поэтому правило сортировки dist/include/%.h:include/%.h не подходит.

ответ

2

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

EXTRA_INSTALL := dist/include/mylib/mylib.h dist/include/mylib/platform.h 

.PHONY: install 
install: $(EXTRA_INSTALL) 

dist/include/mylib/mylib.h: include/mylib/mylib.h 
dist/include/mylib/platform.h: include/mylib/platform/linux/platform.h 

.SECONDEXPANSION: 
$(EXTRA_INSTALL): $$^ 
    cp $^ [email protected] 

Вы также можете отказаться от .SECONDEXPANSION полностью за счет дополнительной линии на файл

EXTRA_INSTALL := dist/include/mylib/mylib.h dist/include/mylib/platform.h 

.PHONY: install 
install: $(EXTRA_INSTALL) 

dist/include/mylib/mylib.h: include/mylib/mylib.h 
    cp $^ [email protected] 
dist/include/mylib/platform.h: include/mylib/platform/linux/platform.h 
    cp $^ [email protected] 
2

Это ужасный хак. Делать такие вещи точно что make для, вам не нужно изобретать свой собственный мини-язык внутри make.

Определит source=target отображения как make предпосылки вместо, а затем определить рецепт для его создания с помощью cp:

dist/include/mylib/mylib.h: include/mylib/mylib.h 
     cp $^ [email protected] 

Это говорит о создании файла dist/include/mylib/mylib.h зависит от другого файла (так он будет воссоздан, если другие изменения файла) и что он должен быть создан путем его копирования.

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

CP := cp -f 
copy_file := $(CP) $(1) $(2) 

dist/include/mylib/mylib.h: include/mylib/mylib.h 
     $(call copy_file,$^,[email protected]) 

dist/include/mylib/platform.h: include/mylib/platform/linux/platform.h 
     $(call copy_file,$^,[email protected]) 
Смежные вопросы