Программирование для Linux. Профессиональный подход - страница 22

стр.

и >cos()), необходимо задать следующую команду:

>% gcc -о compute compute.c -lm

При компоновке программ, написанных на C++, компилятор >c++ или >g++ автоматически подключает к ним стандартную библиотек языка C++: >libstdc++.

2.3.4. Зависимости между библиотеками

Библиотеки часто связаны одна с другой. Например, во многих Linux-системах есть библиотека >libtiff, содержащая функции чтения и записи графических файлов формата TIFF. Она, в свою очередь, использует библиотеки >libjpeg (подпрограммы обработки JPEG-изображений) и >libz (подпрограммы сжатия).

В листинге 2.9 показана небольшая программа, использующая функции библиотеки >libtiff для работы с TIFF-файлом.

Листинг 2.9. (tifftest.c) Применение библиотеки >libtiff

>#include

>#include


>int main(int argc, char** argv) {

> TIFF* tiff;

> tiff = TIFFOpen(argv[1], "r");

> TIFFClose(tiff);

> return 0;

>}

При компиляции этого файла необходимо указать флаг >-ltiff:

>% gcc -о tifftest tifftest.c -ltiff

По умолчанию будет скомпонована совместно используемая версия библиотеки: >/usr/lib/libtiff.so. В связи с тем что она обращается к библиотекам >libjpeg и >libz (одна совместно используемая библиотека может ссылаться на другие аналогичные библиотеки, от которых она зависит), будут также подключены их совместно используемые версии. Чтобы проверить это, воспользуемся командой >ldd:

>% ldd tifftest

> libtiff.so.3 => /usr/lib/libtiff.so.3 (0x4001d000)

> libc.so.6 => /lib/libc.so.6 (0x40060000)

> libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x40155000)

> libz.so.1 => /usr/lib/libz.so.1 (0x40174000)

> /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

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

>% gcc -static -о tifftest tifftest.с -ltiff

>/usr/bin/../lib/libtiff.a(tif_jpeg.o): In function

>                                       'TIFFjpeg_error_exit':

>tif_jpeg.о(.text+0x2a): undefined reference to 'jpeg_abort'

>/usr/bin/../lib/libtiff.a (tif_jpeg.o): In function

>                                        'TIFFjpeg_create_compress':

>tif_jpeg.o(.text+0x8d): undefined reference to 'jpeg_std_error'

>tif_jpeg.o(.text+0xcf): undefined reference to

>                        'jpeg_CreateCompress'

>...

В случае статической компоновки программы нужно самостоятельно указать две другие библиотеки:

>% gcc -static -o tifftest tifftest.c -ltiff -ljpeg -lz

Иногда между двумя библиотеками образуется взаимная зависимость. Другими словами, первый архив ссылается на символические константы, определенные во втором архиве, и наоборот. Такая ситуация, как правило, является следствием неправильного проектирования. В этом случае нужно указать в командной строке одну и ту же библиотеку несколько раз. Компоновщик просмотрит библиотеку столько раз, сколько она присутствует в командной строке. Рассмотрим пример:

>% gcc -o app арр.о -lfoo -lbar -lfoo

Теперь, даже если библиотека >libfoo.a ссылается на символические константы в библиотеке >libbar.a и наоборот, программа будет успешно скомпонована.

2.3.5. Преимущества и недостатки библиотек

Познакомившись со статическими архивами и совместно используемыми библиотеками. читатели, очевидно, задумались: какие же из них лучше использовать? Есть несколько важных моментов, о которых следует помнить.

Большим преимуществом совместно используемой библиотеки является то. что она экономит место на диске при инсталляции программы. Когда устанавливаются десять программ и все они работают с одной и той же библиотекой, экономия может оказаться весьма существенной, тогда как статический архив будет включен во все десять программ. Уменьшается также время загрузки, если программа загружается из Internet.

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