Это исправленный и дополненный перевод статьи о многофункциональной системе сборки Waf.
С самого начала использования сервиса Dropbox для хранения моих научных исследований и проектов я стал искать решение, которое позволит мне строить документы LaTeX без засорения каталога с документом. В обычных условиях я просто игнорирую такие файлы, но под Dropbox, каждый раз после построения документа файлы начинают синхронизироваться с сервером. Так как в Dropbox нет возможности указать файлы для игнорирования (если кто-то из компании читает это сообщение, пожалуйста, сделайте файл .dropboxignore), то я начал искать другое решение.
В начале я использовал Makefile с последовательностью команд, которая делала копию каталога с проектом, переходила во временный каталог, а после чего выполняла требуемые команды.
Хотя такое решение и работало, но оно не позволяло делать что-нибудь нетривиальное. Я мог вместо перемещения проекта во временный каталог использовать один из больших Makefile для Latex, выполняющих более сложные задачи, такие как автоматическое определение зависимостей и т.п. Однако совмещение временного каталога для сборки с нетривиальным make-фалом является весьма непростой задачей.
Несколько месяцев назад я увидел сообщение в блоге Alan LaMielle, в котором он рассказывал об опыте использования системы сборки waf. Waf написан на Python и позицируется как билдовая система с поддержкой настоящего языка программирования и являющаяся мощным инструментом, что на мой взгляд полностью соответствует действительности. Waf распространяется как одиночный python-скрипт, который при первом запуске распаковывает библиотеку в скрытый каталог и начинает работу. Он поставляется с поддержкой нескольких языков программирования, включая Go, Python, LaTeX и даже старого доброго C. Скрипты описанные далее должны без проблем работать с waf, начиная с версии 1.6, который включает все требуемые возможности.
Настройка waf заключается в написании python-скрипта с именем wscript, который и помещается в каталог с вашим проектом. Файл содержит детали, касающиеся сборки вашего проекта. Для документа LaTeX, который я сейчас пишу, я использую wscript со следующим содержимым:
Перед тем как начать строить документ в первый раз, я запускаю
чтобы установить каталог для сборки. Если мне захочется посмотреть результирующий PDF, то я просто добавляю опцию --view.
Типичный файл wscript содержит функцию конфигурации configure, которая вызывается когда пользователь выполняет waf configure. В нашем функции мы убеждаемся, что присутствуют инструменты для работы с tex (за это отвечает строчка conf.check_tool('tex')) и утилита pdflatex. Кроме того, для сборки нам требуется утилита командной строки dot, существование которой мы также проверяем. Вот пример типичного вывода операции waf configure:
Как вы видите скрипт конфигурации нашел все необходимые программы и произвел настройку системы сборки.
Функция сборки достаточно прямолинейна и понятна: сначала мы итерируемся по всем .dot-файлам в каталоге, добавляя правило сборки для каждого из них. Данное правило создает маппинг из .dot-файла в .pdf-файл и везде, где эти .pdf-файлы включаются в оригинальный LaTeX-документ билдовая система добавляет зависимость. В результате, при изменении исходного .dot-файла автоматически будут перестроены .pdf-файлы для этого изображения и главного документа.
Вызов bld.add_group() говорит о том, что элементы первой группы должны быть построены до элементов второй. Вторая группа содержит правила сборки, использующие программы из пакета Latex. Определяется инструмент для сборки (pdflatex) и имя исходного документа.
Последний штрих процесса построения — проверка опции view. Если данная опция присутствует, то мы указываем системе, что после сборки необходимо вызвать пользовательскую функцию view_pdf. Данная функция просто запускает системную команду и открывает результирующий PDF-файл.
Опция view определяется внутри функции опций (options) и задается пользователем с помощью аргумента коммандной строки --view.
Если вы захотите использовать приведенный выше wscript, то вам необходимо поменять в нем имя исходного документа. Далее вы должны выполнить waf configure, а после waf build, чтобы построить документ. Ваш документ, возможно, будет проще, поэтому вы можете ознакомится с примером соответствующего wscript для LaTeX из репозитория waf.
Преимущество построения документа с помощью Waf в том, что автоматически отслеживаются зависимости оригинального документа (система проводит сканирование исходных tex-файлов), поэтому любые изменения в файлах от которых зависит документ (включая файлы с графикой) вызовут перестройку финального pdf.
Ссылки:
С самого начала использования сервиса Dropbox для хранения моих научных исследований и проектов я стал искать решение, которое позволит мне строить документы LaTeX без засорения каталога с документом. В обычных условиях я просто игнорирую такие файлы, но под Dropbox, каждый раз после построения документа файлы начинают синхронизироваться с сервером. Так как в Dropbox нет возможности указать файлы для игнорирования (если кто-то из компании читает это сообщение, пожалуйста, сделайте файл .dropboxignore), то я начал искать другое решение.
Темные времена: Makefile
В начале я использовал Makefile с последовательностью команд, которая делала копию каталога с проектом, переходила во временный каталог, а после чего выполняла требуемые команды.
PROJECTNAME := thesisIntro<br/>
TMPDIR := /tmp/latexBuild.$(PROJECTNAME)/<br/>
<br/>
view: pdf<br/>
-cd $(TMPDIR) && open -a Preview introduction.pdf<br/>
<br/>
pdf: setup<br/>
-cd $(TMPDIR) && pdflatex introduction<br/>
<br/>
setup:<br/>
-rm -fr $(TMPDIR)<br/>
-mkdir $(TMPDIR)<br/>
-cp -R * $(TMPDIR)<br/>
<br/>
clean:<br/>
-rm -fr $(TMPDIR)<br/>
Хотя такое решение и работало, но оно не позволяло делать что-нибудь нетривиальное. Я мог вместо перемещения проекта во временный каталог использовать один из больших Makefile для Latex, выполняющих более сложные задачи, такие как автоматическое определение зависимостей и т.п. Однако совмещение временного каталога для сборки с нетривиальным make-фалом является весьма непростой задачей.
Новая альтернатива: Waf
Несколько месяцев назад я увидел сообщение в блоге Alan LaMielle, в котором он рассказывал об опыте использования системы сборки waf. Waf написан на Python и позицируется как билдовая система с поддержкой настоящего языка программирования и являющаяся мощным инструментом, что на мой взгляд полностью соответствует действительности. Waf распространяется как одиночный python-скрипт, который при первом запуске распаковывает библиотеку в скрытый каталог и начинает работу. Он поставляется с поддержкой нескольких языков программирования, включая Go, Python, LaTeX и даже старого доброго C. Скрипты описанные далее должны без проблем работать с waf, начиная с версии 1.6, который включает все требуемые возможности.
Настройка waf заключается в написании python-скрипта с именем wscript, который и помещается в каталог с вашим проектом. Файл содержит детали, касающиеся сборки вашего проекта. Для документа LaTeX, который я сейчас пишу, я использую wscript со следующим содержимым:
#! /usr/bin/env python<br/>
<br/>
top = '.'<br/>
out = '/tmp/wafbuild-dphilconf'<br/>
<br/>
def configure(conf):<br/>
conf.check_tool('tex')<br/>
conf.find_program('dot', var="DOT")<br/>
if not conf.env.PDFLATEX:<br/>
conf.fatal('could not find the program pdflatex')<br/>
<br/>
def view_pdf(bld):<br/>
bld.exec_command("open -a Preview \"{0}/dphilconf2010.pdf\"".format(out))<br/>
<br/>
def build(bld):<br/>
# Создаем правило, которое преобразует любой .dot-файл в pdf<br/>
for x in bld.path.ant_glob('*.dot'):<br/>
tg = bld(rule='${DOT} -Tpdf -o${TGT[0].get_bld().abspath()} ${SRC[0].abspath()}', source=x, target=x.change_ext('.pdf'))<br/>
<br/>
bld.add_group()<br/>
<br/>
obj = bld(<br/>
features = 'tex',<br/>
type = 'pdflatex',<br/>
source = 'dphilconf2010.tex',<br/>
)<br/>
<br/>
if bld.options.view:<br/>
bld.add_post_fun(view_pdf)<br/>
<br/>
def options(opt):<br/>
opt.tool_options('tex')<br/>
<br/>
# Добавляем опцию командной строки<br/>
opt.add_option('--view', action='store_true', default=False, help='View the document')<br/>
Описание: waf configure
Перед тем как начать строить документ в первый раз, я запускаю
python waf configure
чтобы установить каталог для сборки. Если мне захочется посмотреть результирующий PDF, то я просто добавляю опцию --view.
Типичный файл wscript содержит функцию конфигурации configure, которая вызывается когда пользователь выполняет waf configure. В нашем функции мы убеждаемся, что присутствуют инструменты для работы с tex (за это отвечает строчка conf.check_tool('tex')) и утилита pdflatex. Кроме того, для сборки нам требуется утилита командной строки dot, существование которой мы также проверяем. Вот пример типичного вывода операции waf configure:
Setting top to : /Users/jnwhiteh/Dropbox/Academic/DPhilConf2010
Setting out to : /tmp/wafbuild-dphilconf
Checking for program tex : /usr/texbin/tex
Checking for program latex : /usr/texbin/latex
Checking for program pdflatex : /usr/texbin/pdflatex
Checking for program bibtex : /usr/texbin/bibtex
Checking for program dvips : /usr/texbin/dvips
Checking for program dvipdf : not found
Checking for program ps2pdf : not found
Checking for program makeindex : /usr/texbin/makeindex
Checking for program pdf2ps : not found
Checking for program dot : /usr/local/bin/dot
'configure' finished successfully (0.088s)
Как вы видите скрипт конфигурации нашел все необходимые программы и произвел настройку системы сборки.
Описание: waf build
Функция сборки достаточно прямолинейна и понятна: сначала мы итерируемся по всем .dot-файлам в каталоге, добавляя правило сборки для каждого из них. Данное правило создает маппинг из .dot-файла в .pdf-файл и везде, где эти .pdf-файлы включаются в оригинальный LaTeX-документ билдовая система добавляет зависимость. В результате, при изменении исходного .dot-файла автоматически будут перестроены .pdf-файлы для этого изображения и главного документа.
Вызов bld.add_group() говорит о том, что элементы первой группы должны быть построены до элементов второй. Вторая группа содержит правила сборки, использующие программы из пакета Latex. Определяется инструмент для сборки (pdflatex) и имя исходного документа.
Последний штрих процесса построения — проверка опции view. Если данная опция присутствует, то мы указываем системе, что после сборки необходимо вызвать пользовательскую функцию view_pdf. Данная функция просто запускает системную команду и открывает результирующий PDF-файл.
Опция view определяется внутри функции опций (options) и задается пользователем с помощью аргумента коммандной строки --view.
Собираем все вместе
Если вы захотите использовать приведенный выше wscript, то вам необходимо поменять в нем имя исходного документа. Далее вы должны выполнить waf configure, а после waf build, чтобы построить документ. Ваш документ, возможно, будет проще, поэтому вы можете ознакомится с примером соответствующего wscript для LaTeX из репозитория waf.
Преимущество построения документа с помощью Waf в том, что автоматически отслеживаются зависимости оригинального документа (система проводит сканирование исходных tex-файлов), поэтому любые изменения в файлах от которых зависит документ (включая файлы с графикой) вызовут перестройку финального pdf.
Ссылки: