Несмотря на то, что на этот вопрос есть принятый ответ, я собираюсь нанести удар.
Заголовок спрашивает, как разделить проект на bpls, но реальный вопрос, по-видимому:
«Какой лучший способ поделиться кодом между проектами?»
Есть несколько способов сделать это:
- Общие единицы
- Dlls
- 1012 * ВР *
Независимо от того, в каком направлении вы идете, вам, скорее всего, придется реструктурировать свои проекты. Из вашего описания звучит так, будто каждый проект разрабатывается в относительной изоляции. Код передается с использованием функции копирования / вставки, что быстро нарушает синхронизацию и приводит к большим дублирующим усилиям. Итак, давайте рассмотрим каждый из методов обмена кодом.
Общие единицы
Это самый простой подход. Вы создаете общее местоположение и размещаете код, который хотите использовать в своих проектах в этом месте. Модули статически связаны с вашими проектами, поэтому вам не нужно беспокоиться о развертывании дополнительных зависимостей вместе с основными исполняемыми файлами. Статически связанные блоки являются наиболее простыми для устранения неполадок и отладки.
Компилятор должен быть в состоянии найти ваши общие модули. Есть 4 способа указать компилятору, где искать.
- Добавить их в проект - SHIFT + F11 - Добавляет ссылку на устройство в файлы проекта (dpr, dproj). В среде IDE обычно используются относительные пути, если устройство находится в том же дереве каталогов, что и файлы проекта, в противном случае будут использоваться абсолютные пути, что может быть проблематично, если машины разработчика не настроены одинаково.
- Путь поиска проекта - CTRL + SHIFT + F11 Delphi Compiler> Путь поиска - Добавить каталог, и компилятор будет посмотрите там, чтобы найти модули, упомянутые в разделе использования любого модуля в проекте. Лучше всего использовать относительные пути, если можете. Вы также можете использовать переменные окружения: $ (MyPath)
- Глобальный путь поиска - Инструменты> Параметры> Параметры среды> Параметры Delphi> Библиотека - Win32> Путь к библиотеке - любые пути, перечисленные здесь, доступны для всех проектов на компьютере. Это зависит от машины
- Командная строка - Если вы строите из скрипта или средства автоматизации сборки, вы можете установить путь поиска с помощью переключателя
-U
dcc32 или /property:UnitSearchPath=
msbuild.
Варианты 1 и 2 будут наиболее полезными.
Что касается вашего репозитория SVN, у вас есть несколько вариантов организации проектов и общих модулей. Простейшим было бы поместить все проекты в одну магистраль вместе с общими блоками:
Projects
trunk
ProjectA
ProjectB
ProjectC
Library (shared units)
Если по какой-либо причине описанная выше структура невозможна, вы можете попробовать эту альтернативу:
ProjectA
trunk
Library (branch of main library)
ProjectB
trunk
Library (branch of main library)
ProjectC
trunk
Library (branch of main library)
Library
trunk (main library)
В этой конфигурации изменения, внесенные в папку библиотеки каждого проекта, не будут немедленно доступны для других проектов. Каждый проект должен будет регулярно синхронизировать изменения с основным проектом библиотеки. Побочным эффектом этого является то, что изменения, которые нарушают другие проекты, будут отложены до синхронизации других проектов. Считаете ли вы это хорошей или плохой вещью, зависит. С одной стороны, ошибки легче и дешевле исправить, если код, который они используют, еще свеж в сознании разработчика. С другой стороны, если вы не практикуете модульное тестирование (что я настоятельно рекомендую вам делать), или код очень хрупкий, или у вас просто есть разработчики, склонные к безрассудным изменениям, вы можете контролировать, как часто эти изменения проталкиваются в другие проекты .
Dlls
Dlls позволяют вам делиться кодом, связываясь с ним во время выполнения. Они предоставляют функции, которые можно вызывать из основного исполняемого файла или другой библиотеки DLL.
Хотя библиотеки DLL всегда связаны во время выполнения, вы решаете, будут ли они загружены при запуске приложения или только при необходимости. Загрузка при запуске называется статическая загрузка , а в Delphi это выполняется с помощью директивы external
. Подавляющее большинство классов rtl / vcl, которые переносят системные вызовы API, используют статическую загрузку. Динамическая загрузка позволяет отложить загрузку DLL, пока она не потребуется. При этом используются функции WinAPI LoadLibrary и GetProcAddress. Соответствующий вызов FreeLibrary выгрузит DLL.
К сожалению, стандартные dll ограничивают типы передаваемых данных. Если вам нужен доступ к DLL из не-Delphi проектов, вам нужно ограничиться использованием типов данных в стиле c. Если вы будете использовать dll только с проектами Delphi, вы можете безопасно использовать строки и динамические массивы Delphi, если вы используете модуль SharedMem в dll и любые проекты, которые его используют.
Вы можете безопасно использовать объекты внутри dll без проблем, но если вы хотите передавать объекты между dll и приложением, вам нужно извлечь данные объекта и передать их как примитивные типы и собрать их в объект на другом конец. Это называется (де) сериализацией или сортировкой, и есть гораздо более простые способы сделать это, чем сворачивать свои собственные.
COM (объектная модель компонентов) хорошо поддерживается в Delphi, но имеет некоторую кривую обучения. Потребление объектов COM довольно просто, но разработка одного займет некоторое время, если вы не знакомы с COM. Преимущество COM заключается в том, что он не зависит от языка и поддерживается на большинстве языков, ориентированных на платформу Windows (включая языки, нацеленные на платформу .NET).
1078 * ВР *
Bpls (также называемые просто «пакетами») - это специально отформатированные dll, которые значительно облегчают работу с объектами. Как и стандартные библиотеки, они связаны во время выполнения и могут быть статически или динамически загружены. Их легче изучать и использовать, чем COM-библиотеки, и они обеспечивают больше интеграции в ваши проекты, чем COM. Пакеты состоят из двух частей: bpl и dcp. Dcp похож на файлы dcu, сгенерированные при компиляции обычного файла модулей, за исключением того, что он содержит целую кучу модулей. Использование класса, скомпилированного в bpl, так же просто, как добавление dcp в список пакетов проекта, а затем добавление модуля в условие использования одного из модулей проекта.
При развертывании приложения вам также необходимо установить bpl. Как уже отмечали другие, вы должны как минимум включать пакет rtl и, скорее всего, пакет vcl, если вы используете какие-либо формы. Существует способ развернуть поставленные Borland BPL с вашими проектами. Вы можете создать «мини» пакет RTL, который содержит только те единицы, которые нужны вашему проекту. Трудно определить, какие единицы включить.
Резюме
Из приведенного вами описания создание библиотеки совместно используемых файлов юнитов для статической ссылки может оказаться наиболее целесообразным путем. Я также предложил бы попробовать программу под названием Simian . Это поможет вам найти дубликаты кода в вашей кодовой базе для включения в общую библиотеку. Он не поддерживает паскаль напрямую, но выполняет достаточно приличную работу, используя анализатор простого текста с небольшой настройкой его конфигурации.
Также я не могу не подчеркнуть ценность модульного тестирования. Особенно, если вы переходите к общим библиотекам. Набор хорошо написанных модульных тестов, запускаемых на регулярной основе, даст вам мгновенную обратную связь, когда разработчик меняет класс и ломает несвязанный проект.