суббота, 2 февраля 2013 г.

pragma comment (lib, ...): Линковка разных библиотечных файлов в зависимости от конфигурации

Предположим, что вы разрабатываете какую-то очень полезную библиотеку. Или не очень полезную. Или уже разработали, давно выложили на github, и развиваете её дальше. Насколько удобно и легко будет включить вашу библиотеку в проект "постороннему" человеку? Назовём его, для определённости, Посторонним В.

Типичный набор действий В. по включению библиотеки в проект:

  1. Прописывает в свойствах проекта путь к заголовочным файлам.
  2. Прописывает в свойствах линковщика путь к библиотекам.
  3. Указывает названия необходимых библиотек.
Всё? Чаще всего, нет. Посторонним В. меняет конфигурацию проекта с Debug на Release (или наоборот), и вписывает всё то же самое. Почти, да не совсем - очень часто путь к Debug и Release версии файлов библиотеки отличается, поскольку по умолчанию названия библиотечных файлов для Debug и Release одинаковые. На случай, если наш В. использует дополнительные конфигурации - кроме стандартных Debug и Release, данное действие повторяется для всех конфигураций.

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

А теперь прекращаем издеваться над В. и остальными, и делаем всё по-человечески.

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

Решением для ряда описанных проблем является простая и замечательная конструкция следующего вида:

  #pragma comment (lib, "library.lib")

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

Для разных конфигураций проекта (Debug, Release, ...) потребуются разные библиотечные файлы. Более того, разные версии библиотеки могут потребоваться в зависимости от того, требуется ли работа в однопоточном или многопоточном режимах, и даже может зависеть от разных версий компилятора. Не забываем и про архитектуру - x86 или x64. Этот вопрос также решается с помощью препроцессора, через стандартные #ifdef вызовы. 

Используя макросы _DEBUG, _DLL, _ST (и другие, при необходимости), можно сформировать имя подключаемой библиотеки "на лету", уже во время компиляции. Разумеется, данная библиотека должна существовать и быть предварительно собрана для каждой необходимой комбинации макросов. Теперь можно положить все файлы библиотек в один каталог, и избавить В. от необходимости гадать, какую же из библиотек необходимо подключить, а также ссылаться на библиотеки используя один и тот же путь для всех конфигураций проекта.

Комментариев нет:

Отправить комментарий