Марк Митчелл - Программирование для Linux. Профессиональный подход
- Название:Программирование для Linux. Профессиональный подход
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2002
- Город:Москва
- ISBN:5-8459-0243-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Марк Митчелл - Программирование для Linux. Профессиональный подход краткое содержание
Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.
Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.
Программирование для Linux. Профессиональный подход - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Затем следует объединить объектные файлы в библиотеку:
% gcc -shared -fPIC -о libtest.so test1.o test2.o
Опция -shared
заставляет компоновщик создать совместно используемую библиотеку, а не обычный исполняемый файл. Такие библиотеки имеют расширение .so
. Подобно статическому архиву, имя библиотеки всегда начинается с префикса lib
, указывающего на то. что файл является библиотекой.
Компоновка совместно используемой библиотеки аналогична компоновке архива. Например, следующая команда подключает к программе файл libtest.so
, если он находится в текущем каталоге или одном из стандартных системных библиотечных каталогов:
% gcc -о app арр.о -L. ltest
Предположим, имеются оба файла: libtest.а
и libtest.so
. Каким образом компоновщик принимает решение? Он просматривает каждый заданный каталог (сначала те, что указаны в опции -L
, затем стандартные) и, как только обнаруживает хотя бы один из файлов, тут же прекращает поиск. Если в найденном каталоге присутствует только один из файлов, он и выбирается. В противном случае выбор делается в пользу совместно используемой библиотеки, если явно не указано обратное. Отдать приоритет статическому архиву позволяет опция -static
. Например, следующая команда подключит к программе архив libtest.a
, даже если присутствует библиотека libtest.so
:
% gcc -static -о app арр.о -L. -ltest
Команда ldd
выводит список совместно используемых библиотек, подключенных к заданному исполняемому файлу. Все они должны быть доступны при запуске программы. Обратите внимание на то, что команда ldd
сообщает о наличии дополнительной библиотеки: ld-linux.so
. Она является частью механизма динамической компоновки в Linux.
Когда к программе подключается совместно используемая библиотека, компоновщик помещает в исполняемый файл ссылку на нее, но в этой ссылке указан не полный путь к библиотеке, а только имя файла. При запуске программы система сама находит библиотеку и загружает ее. По умолчанию система просматривает лишь каталоги /lib
и /usr/lib
. Если библиотека находится в другом каталоге, она не будет найдена и система откажется загружать программу.
Одно из решений заключается в компоновке программы с указанием флага -Wl,-rpath
:
% gcc -о app арр.о -L. -ltest -Wl,-rpath,/usr/local/lib
Теперь в случае запуска программы app
система будет искать требуемые библиотеки также в каталоге /usr/local/lib
.
Но есть и другое решение: устанавливать переменную LD_LIBRARY_PATH
при запуске программы. Подобно переменной среды PATH
, переменная LD_LIBRARY_PATH
представляет собой разделенный двоеточиями список каталогов. Если, к примеру, она равна /usr/local/lib:/opt/lib
, то каталоги /usr/local/lib
и /opt/lib
будут просматриваться перед стандартными каталогами /lib
и /usr/lib
. Необходимо также учитывать, что при наличии данной переменной компоновщик будет просматривать заданные в ней каталоги, обнаруживая опцию -L
в командной строке. [9] Иногда в документации упоминается переменная LD_RUN_PATH . Не верьте прочитанному! Данная переменная никак не используется в Linux.
2.3.3. Стандартные библиотеки
Даже если при компоновке программы не были заданы библиотеки, все равно одна из них почти наверняка присутствует. Дело в том, что компилятор gcc
автоматически подключает к программе стандартную библиотеку языка С: libc
. В нее, однако, не входят математические функции. Они находятся в отдельной библиотеке, libm
, которую нужно компоновать явно. Например, чтобы скомпилировать и скомпоновать программу compute
, использующую тригонометрические функции (такие как sin()
и cos()
), необходимо задать следующую команду:
% gcc -о compute compute.c -lm
При компоновке программ, написанных на C++, компилятор c++
или g++
автоматически подключает к ним стандартную библиотек языка C++: libstdc++
.
2.3.4. Зависимости между библиотеками
Библиотеки часто связаны одна с другой. Например, во многих Linux-системах есть библиотека libtiff
, содержащая функции чтения и записи графических файлов формата TIFF. Она, в свою очередь, использует библиотеки libjpeg
(подпрограммы обработки JPEG-изображений) и libz
(подпрограммы сжатия).
В листинге 2.9 показана небольшая программа, использующая функции библиотеки libtiff
для работы с TIFF-файлом.
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
и наоборот, программа будет успешно скомпонована.
Интервал:
Закладка: