Установите дерево каталога данных с большим количеством файлов, используя automake
У меня есть каталог данных, который я хотел бы automake для создания целей установки и удаления. По сути, я просто хочу скопировать этот каталог в каталог DATA. Обычно я могу перечислить все файлы по отдельности, например
dist_whatever_DATA=dir/subdir/filea ...
Но проблема возникает, когда моя структура каталогов выглядит так:
*root
*subdir
*~10 files
*subdir
*~10 files
*subdir
*~700 files
*subdir
...
~20 subdirs
Я просто не могу перечислить все 1000+ файлов, включенных как часть моего Makefile.am. Это было бы смешно.
Мне также нужно сохранить структуру каталогов. Я должен отметить, что эти данные вообще не генерируются процессом сборки и на самом деле являются в значительной степени короткими аудиозаписями. Поэтому мне не хотелось бы, чтобы automake "проверял", что каждый файл, который я хочу установить, фактически был создан, поскольку они либо есть, либо нет, и какой бы файл там ни был, я знаю, что хочу, чтобы он был установлен, и что бы ни было файла нет, его не следует устанавливать. Я знаю, что это оправдание, используемое в других местах, чтобы не делать подстановочные знаки, но все возможные причины здесь не применимы.
Ответы
Ответ 1
Я обнаружил, что установка сотен файлов по отдельности делает мучительно длинный вызов make install
. У меня был аналогичный случай, когда я хотел установить сотни файлов, сохраняя структуру каталогов, и я не хотел менять свой Makefile.am каждый раз, когда файл был добавлен или удален из коллекции.
Я включил архив LZMA в файлы в моем дистрибутиве и сделал такие правила automake как:
GIANTARCHIVE = My_big_archive.tar.lz
dist_pkgdata_DATA = $(GIANTARCHIVE)
install-data-hook:
cd $(DESTDIR)$(pkgdatadir); \
cat $(GIANTARCHIVE) | unlzma | $(TAR) --list > uninstall_manifest.txt; \
cat $(GIANTARCHIVE) | unlzma | $(TAR) --no-same-owner --extract; \
rm --force $(GIANTARCHIVE); \
cat uninstall_manifest.txt | sed --expression='s/^\|$$/"/g' | xargs chmod a=rX,u+w
uninstall-local:
cd $(DESTDIR)$(pkgdatadir); \
cat uninstall_manifest.txt | sed --expression='s/ /\\ /g' | xargs rm --force; \
rm --force uninstall_manifest.txt
Таким образом, automake устанавливает My_big_archive.tar.lz
в каталог $(pkgdata)
и извлекает его там, составляя список всех файлов, которые были в нем, поэтому он может удалить их позже. Это также работает намного быстрее, чем перечисление каждого файла в качестве цели установки, даже если вы должны автогенерировать этот список.
Ответ 2
Я бы использовал script для генерации фрагмента Makefile
, в котором перечислены все файлы:
echo 'subdir_files =' > subfiles.mk
find subdir -type f -print | sed 's/^/ /;$q;s/$/ \\/' >> subfiles.mk
а затем включите этот subfiles.mk
из основного Makefile.am
:
include $(srcdir)/subfiles.mk
nobase_dist_pkgdata_DATA = $(subdir_files)
Вторая опция - EXTRA_DIST = subdir
, а затем для написания пользовательских правил install-data-local
и uninstall-local
.
Проблема заключается в том, что EXTRA_DIST = subdir
будет распространять все файлы в subdir/
, включая файлы резервных копий, файлы конфигурации (например, из вашего VCS) и другие вещи, которые вы не хотели бы распространять.
Используя script, как описано выше, вы можете фильтровать файлы, которые вы действительно хотите распространять.
Ответ 3
Я бы написал script (либо в виде отдельной оболочки script, либо в Makefile.am
), которая запускается как часть install-data-hook
.