Установите дерево каталогов данных с огромным количеством файлов, используя automake - PullRequest
15 голосов
/ 18 июня 2011

У меня есть каталог данных, для которого я хотел бы, чтобы 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 «проверяла», что каждый файл, который я хочу установить, действительно был создан, поскольку он либо есть, либо нет, и какой бы файл там ни был, я знаю, я хочу, чтобы он был установлен, и все, что угодно файла нет, не должен быть установлен. Я знаю, что это оправдание, используемое в других местах, чтобы не делать групповые инсталляции, но все возможные причины здесь не применимы.

Ответы [ 3 ]

11 голосов
/ 18 июня 2011

Я бы использовал скрипт для генерации фрагмента 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) и другие вещи, которые вы не хотели бы распространять.

Использование сценария, описанного выше, позволяет фильтровать файлы, которые вы действительно хотите распространять.

10 голосов
/ 20 июня 2011

Я обнаружил, что установка сотен файлов по отдельности приводит к мучительно долгому вызову make install. У меня был похожий случай, когда я хотел установить сотни файлов, сохраняя структуру каталогов, и я не хотел менять свой Makefile.am каждый раз, когда файл добавлялся в коллекцию или удалялся из нее.

Я включил LZMA-архив файлов в свой дистрибутив и сделал правила автоматического создания примерно такими:

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) и извлекает его там, создавая список всех файлов, которые были в нем, чтобы он мог удалить их позже. Это также выполняется намного быстрее, чем перечисление каждого файла в качестве цели установки, даже если вы должны были автоматически сгенерировать этот список.

3 голосов
/ 19 июня 2011

Я бы написал сценарий (либо в виде отдельного сценария оболочки, либо в Makefile.am), который запускается как часть цели install-data-hook.

...