Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Contingent: Динамическая система сборки

Оригинал: Contingent: A Fully Dynamic Build System
Авторы: Brandon Rhodes, Daniel Rocco
Дата публикации: July 12, 2016
Перевод: Н.Ромоданов
Дата перевода: январь 2017 г.

Creative Commons

Перевод был сделан в соответствие с лицензией Creative Commons. С русским вариантом лицензии можно ознакомиться здесь.

Брэндон Родс начал использовать язык Python в конце 1990-х годов, и в течение 17 лет поддерживал библиотеку PyEphem, предназначенную для астрономов-любителей. Он работает в компании Dropbox, проводит курсы программирования на языке Python для корпоративных клиентов, консультирует по таким проектам, как, например, реализация на Django сайта New England Wildflower Society's “Go Botany”, а также будет председателем конференций PyCon в 2016 и 2017 годах. Брэндон считает, что хорошо написанный код является видом литературного произведения, который, если он красиво отформатирован, является произведением графического дизайна, и что правильный код является одним из наиболее понятных форм мышления.

Даниэлю Рокко нравится язык Python, кофе, крепкое пиво, объектный и системный дизайн, шоколадный бисквит, учеба и игра на гитаре. Он рад тому, что пишет на языке Python для различных жизненных ситуаций, он всегда ищет возможность научиться чему-нибудь у других, а также внести свой вклад обучая других тому, что он знает. Он часто выступает на конференциях PyAtl с темами, посвященными вводным вопросам, тестированию, дизайну и острым темам; он любит видеть удивление и восторг в глазах людей, когда кто-то рассказывает о новой, удивительной или красивой идее. Он живет в Атланте.

Введение

Системы сборки уже давно являются стандартным инструментом в программировании.

Стандартная система сборки make, автор которой получил премию ACM Software System, была впервые разработана в 1976 г. Она не только позволяет вам указать, что выходной файл зависит от одного (или более) исходных файлов, но позволяет делать это рекурсивно. Программа, например, может зависеть от объектного файла, который сам по себе зависит от соответствующего файла с исходным кодом:

    prog: main.o
            cc -o prog main.o

    main.o: main.c
            cc -C -o main.o main.c

Если открыть файл make, то увидим, что при следующем вызове файл main.c с исходным кодом будет иметь более позднее время модификации, чем файл main.o, и будет пересобираться не только объектный файл main.o, но также и сам файл prog.

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

Т.к. системы сборки используются в течение десятилетий, то можно было бы ожидать, что уже они стали абсолютно универсальными и их можно применять даже в случае самых экстравагантных условиях. Но, в действительности, есть одна проблема взаимосвязи собираемых артефактов – проблема динамических перекрестных ссылок, которая в большинстве систем сборки обрабатывается настолько плохо, что мы посвятили данную главу не только классическому ее решению и структурам данных, используемых для решения проблемы make, но и значительно расширили это решение, причем для вполне конкретной области применения.

Проблема, опять же, перекрестные ссылки. Где перекрестные ссылки, как правило, появляются? В текстовых документах, документации и в напечатанных книгах!

Проблема: Системы сборки документов

Всегда кажется, что системы, которые пересобирают отформатированные документы из исходных, делают либо слишком много работы, либо слишком мало.

Они делают слишком много работы, когда они реагируют на незначительные изменения, заставляя вас ждать пока несвязанные между собой главы будут повторно проанализированы и пересобраны. Но они также могут выполнять слишком мало работы, когда возвращают нам несогласованный итоговый результат.

Рассмотрим систему Sphinx, сборщик документации, который используется как для сборки официальной документации языка Python, так и для многих других проектов, реализованных сообществом языка Python. Файл index.rst проекта Sphinx, как правило, имеет следующий вид:

   Table of Contents
   =================

   .. toctree::

      install.rst
      tutorial.rst
      api.rst

Этот список файлов с названием глав указывает системе Sphinx, что когда она будет собирать выходной файл index.html, то должна будет добавить ссылки на каждую из трех указанных глав. Также внутри каждой из глав будут ссылки на все разделы. Если убрать разметку, то текст, полученный в результате выполнения команды toctree для данного заголовка, может выглядеть следующим образом:

  Table of Contents

  • Installation

  • Newcomers Tutorial
      • Hello, World
      • Adding Logging

  • API Reference
      • Handy Functions
      • Obscure Classes

Видно, что такое содержание представляет собой смесь данных, полученных из четырех различных файлов. Хотя порядок следования глав и структура содержания берется из файла index.rst, название каждой главы и раздела берутся из других трех исходных файлов.

Если позже вам потребуется изменить название одной из глав данного руководства пособия - в конце концов, слово "первооткрывать" ("newcomer") звучит несколько необычно, как будто бы ваши пользователи являются поселенцами, которые только что прибыли в штата Вайоминг для его заселения, то можно будет изменить первую строку файла tutorial.rst и записать что-нибудь более подходящее:

  -Newcomers Tutorial
  +Beginners Tutorial
   ==================

   Welcome to the tutorial!
   This text will take you through the basics of...

Когда вы будете готовы к пересборке, система Sphinx сделает именно то, что нужно! Она пересоберет оба файла, содержащие главы, и общий индекс. (Перенаправление данных по конвейеру с помощью команды cat позволит системе Sphinx объявлять о каждом пересобранном файле в отдельной строке, а не использовать просто команду возврата каретки для многократной перезаписи одной и той же строки с обновленными процентными значениями результата работы).

   $ make html | cat
   writing output... [ 50%] index
   writing output... [100%] tutorial

Поскольку система Sphinx принимает решение пересобрать оба документа, то в таблице с содержимым будет теперь указан не только заголовок из файла tutorial.html, но и обновленный заголовок раздела из файла index.html. Система Sphinx пересобирет все файлы для того, чтобы обеспечить согласованность результата.

А что, если ваши изменения в tutorial.rst не столь большие?

   Beginners Tutorial
   ==================

  -Welcome to the tutorial!
  +Welcome to our project tutorial!
   This text will take you through the basics of...

В этом случае нет необходимости в пересборке файла index.html, т. к. небольшие изменения внутри абзаца не изменяет какой-либо информации в таблице содержания. Но выясняется, что система Sphinx не столь умна, как это могло первоначально показаться! Она продолжит свою деятельность и даже в том случае, если в результате содержание будет точно таким же, она выполнит лишнюю работу по пересборке файла index.html.

   writing output... [ 50%] index
   writing output... [100%] tutorial

Вы можете запустить команду diff для версий "до" и "после" пересборки файла index.html для того, чтобы удостовериться, что ваше минимальное исправление не оказало никакого влияния на первую страницу - в любом случае система Sphinx заставит вас еще ожидать, пока этот файл не будет пересобран.

Для небольших документов, которые легко собирать, вы можете даже не заметить лишние затраты на пересборку. Но задержки в рабочем процессе могут стать существенными, когда вы делаете частые улучшения и изменения в документах, которые длинные, сложные или в которых генерируются мультимедийные данные, такие как графики или анимации. Хотя система Sphinx не выполняет пересборку каждой главы, когда вы делаете одиночное изменение - она, например, не будет пересобирать файл install.html или api.html в случае, если вы отредактировали файл tutorial.rst - она делает больше, чем нужно.

Но, как выясняется, система Sphinx делает кое-что еще хуже: она иногда делает слишком мало, выдавая вам несогласованные выходные данные, на которые могут обратить внимание пользователи.

Для того, чтобы обнаружить один из простейших примеров неверной работы, сначала добавьте перекрестную ссылку в верхнюю часть документации по API:

   API Reference
   =============

  +Before reading this, try reading our :doc:`tutorial`!
  +
   The sections below list every function
   and every single class and method offered...

Система Sphinx со своей обычной аккуратностью, касающийся таблицы содержания, будет пересобирать этот ссылочный документ по API и домашнюю страницу index.html вашего проекта:

   writing output... [ 50%] api
   writing output... [100%] index

Вы можете убедиться, что в выходной файл api.html система Sphinx включила красивый удобочитаемый заголовок главы руководства внутри тега с перекрестной ссылкой:

   <p>Before reading this, try reading our
   <a class="reference internal" href="tutorial.html">
   <em>Beginners Tutorial</em>
   </a>!</p>

А что, если вы теперь еще сделаете изменения в заголовке в верхней части файла tutorial.rst? У вас теперь три устаревших файла:

  1. Заголовок в верхней части файла tutorial.html теперь устарел, поэтому этот файл необходимо пересобрать.
  2. Таблица содержания в файле index.html все еще содержит старое название, поэтому этот документ необходимо пересобрать.
  3. Вставленная перекрестная ссылки в первом абзаце файла api.html все еще содержит старое название главы, и поэтому этот файл также должен быть пересобран.

А что же делает система Sphinx?

   writing output... [ 50%] index
   writing output... [100%] tutorial

Проблема.

Были пересобраны только два файла, а не три. Системы Sphinx не удалось правильно пересобрать вашу документацию.

Если теперь вы поместите ваши файлы HTML в сеть, то пользователи увидят старое название в перекрестной ссылке в верхней части файла api.html, однако как только они перейдут по ссылке на файл tutorial.html, они увидят другое название - новое. Это может произойти со многими видами перекрестных ссылок, которые обрабатывает система Sphinx: названия глав, заголовки разделов, пунктов, классов, методов и функций.

Перейти к следующей части статьи.