- PVSM.RU - https://www.pvsm.ru -

Компиляция программного проекта на Fortran

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

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

Напомним, что файлы в фортрановском проекте зависят друг от друга через модули. Если в одном файле есть module A, а в другом — use A, то первый файл должен быть скомпилирован раньше. При этом подобная информация нигде не прописывается и генерируется на лету. Интеграция компилятора Intel Fortran с Visual Studio в большинстве случаев правильно определяет последовательность компиляции, однако и она может ошибиться, что уж говорить о специальных утилитах, нацеленных на создание make-файлов.

Ниже приводится метод определения зависимостей в файлах проекта и описание процесса автоматической сборки проекта без использования специальных программ.

Поставим задачу в таком виде: автоматически собрать проект, имея на входе только исходные файлы проекта, проект vfproj и в общем случае файл sln.

Вероятно, некоторые существующие методы построения exe-файла требуют вызова специальной промежуточной утилиты, генерирующей по файлу проекта (vfproj) зависимости в виде make-файла.
Поиски такой утилиты к успеху не привели. Да и бывает, что после успешной компиляции и компоновки в студии возможна повторная компиляция некоторых файлов из-за неверно определённых зависимостей, неверной трактовки условной компиляции (!DEC$) и т.п. Таким образом, внешние утилиты не могут считаться надёжным способом определения порядка компиляции.

Задача делится на две:

  1. файл проекта (который хранится в формате XML) переписать в виде списка файлов с параметрами компиляции.
  2. скомпилировать в нужном порядке.

Первая задача решается несложно. Создаётся соответствие атрибутов в формате XML параметрам компилятора. Пример: вместо WarnUnusedVariables="true" подставляем /warn:unused. К слову, такой подход настраивает на критическую оценку настроек уже имеющегося проекта, можно выкинуть лишние настройки, понять, поменять назначение уже имеющихся.

Для решения второй задачи был избран следующий подход: ловить зависимости на основе поведения самого компилятора. предположим, что программа правильно написана с точки зрения компилятора:
каждый программист регулярно проводит компиляцию всего проекта для проверки реализованной функциональности. Тогда компиляция файла может завершиться либо успешно, либо в случае отсутствия модуля первой ошибкой будет Module not found. Запоминаем имя отсутствующего модуля и переходим к следующему файлу в списке.

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

Далее, когда компилятор ошибок не выдаёт, мы смотрим, какие модули создались. Если находим, какой-то из предыдущих файлов не был скомпилирован из-за отсутствия такого модуля,
можем его скомпилировать повторно.

Порядок компиляции фиксируем в репозитории. Промежуточные объектные файлы можно удалить.
В следующий раз лишнее время на компиляцию мы не потратим. Если зависимости немного изменились, повторно всю цепочку с нуля мы прослеживать уже не будем.

Отметим, что здесь речь не идёт об ускорении сборки проекта [1] и make-файлы в обычном понимании этого слова не создаются.

Особенности реализации

Возможно использование языка VBScript, поскольку под Windows никакой компилятор для него устанавливать не требуется. Автор использовал именно VBScript во многом по этой причине:
настроить компиляцию можно на любом компьютере с ОС Windows, которых в офисе абсолютное большинство. В VBScript есть встроенное чтение и поддержка файлов XML, что актуально для проектов, хранимых в таком формате. Переписывать скрипт для ОС Linux до сих пор не требовалось.

Особое внимание в VBScript требуется уделить перехвату буфера вывода, с которым, как известно, есть определённые проблемы. Для контроля и перехвата стандартного и ошибочного вывода требуется использовать вызов WSHShell.Exec. Для тех же целей требуется установить лимит на время выполнения одной компиляции. Связанная проблема — если программа сложная, компилятор может зависнуть, если скомпилировать произвольный файл из проекта, — просто из-за несовершенства компилятора. Первый запуск, таким образом, может оказаться довольно долгим.

Ещё некоторый недостаток — если VBScript работает не в режиме консольного окна,
то будут постоянно выскакивать чёрные консольные окна для каждого компилируемого файла.
А в режиме консольного окна всё время открыто одно окно скрипта. Поскольку весь процесс запускается ночью, либо на сервере сборки-тестирования, такое поведение приемлемо.

К слову

Скрипт можно использовать ещё для одной цели. Дело в том, что за день код может быть испорчен, так что компиляция не пройдёт и тесты запущены не будут, что будет очень печально, если тесты отрабатывают за время порядка нескольких часов. Так что даже в случае очень простой для исправления ошибки проверка и запуск днём приведёт к потере времени.

Легко и просто настроить проверку компилируемости скажем в 19—20—21 час вечера. Допустим, в команде есть человек, умеющий исправить случайно испорченный код. Тогда если проект не собрался, можно настроить отправку смс на телефон об этой проблеме, так что как минимум утром будет существовать собранный экзешник, с результатами тестирования.

Отправить смс на конкретный номер телефона с согласия абонента можно без привлечения специальных сервисов [2], бесплатно (см. посты 76867 [3] и 81630 [4]).

Автор: DKov


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/razrabotka/12485

Ссылки в тексте:

[1] ускорении сборки проекта: http://habrahabr.ru/post/130914

[2] специальных сервисов: http://habrahabr.ru/post/147583/

[3] 76867: http://habrahabr.ru/post/76867/

[4] 81630: http://habrahabr.ru/post/81630/