16.3.7. Команда pkg-config
Существует настолько много библиотек сторонних разработчиков, что размещение их всех в общем расположении может привести к путанице. Однако и установка каждой из них с помощью отдельного префикса может вызвать проблемы, когда при сборке пакетов эти библиотеки понадобятся. Если, например, вы желаете скомпилировать пакет OpenSSH, вам необходима библиотека OpenSSL. Как сообщить процессу конфигурирования пакета OpenSSH о том, где расположены библиотеки OpenSSL и какие из них потребуются?
Многие пакеты используют теперь команду pkg-config не только для информирования о местоположении своих включаемых файлов и библиотек, но также и для указания точных флагов, которые вам необходимы для компиляции и сборки программ. Синтаксис выглядит так:
$ pkg-config options package1 package2 ...
Чтобы, например, отыскать библиотеки, необходимые для пакета OpenSSL, можно запустить следующую команду:
$ pkg-config —libs openssl
Результат будет вроде этого:
-lssl -lcrypto
Чтобы увидеть список всех библиотек, о которых знает команда pkg-config, запустите такую команду:
$ pkg-config —list-all
Как работает команда pkg-config
Если заглянуть за кулисы, то можно обнаружить, что команда pkg-config отыскивает информацию о пакете, читая файл конфигурации, имя которого оканчивается на .pc. Вот пример того, так выглядит файл openssl.pc для библиотеки сокетов OpenSSL в системе Ubuntu (он расположен в каталоге /usr/lib/i386-linux-gnu/pkgconfig):
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib/i386-linux-gnu
includedir=${prefix}/include
Name: OpenSSL
Description: Secure Sockets Layer and cryptography libraries and tools
Version: 1.0.1
Requires:
Libs: -L${libdir} -lssl -lcrypto
Libs.private: -ldl -lz
Cflags: -I${includedir} exec_prefix=${prefix}
Можно изменить этот файл, добавив, например, флагам библиотеки параметр -Wl,-rpath=${libdir}, чтобы указать путь динамической компоновки времени исполнения. Однако на первом месте остается более серьезный вопрос: как команда pkg-config отыскивает файлы .pc? По умолчанию команда pkg-config смотрит каталог lib/pkgconfig в соответствии с префиксом установки. Например, команда pkg-config, установленная с префиксом /usr/local, будет смотреть каталог /usr/local/lib/pkgconfig.
Установка файлов команды pkg-config в нестандартных размещениях
К сожалению, по умолчанию команда pkg-config не читает никаких файлов .pc за пределами своего каталога установки. Если файл .pc находится в нестандартном месте, например в каталоге /opt/openssl/lib/pkgconfig/openssl.pc, то он будет недоступен для любой стандартно установленной команды pkg-config. Есть два основных способа сделать файлы .pc доступными за пределами каталога установки команды pkg-config.
• Создать символические ссылки (или копии) из реальных файлов .pc в основном каталоге pkgconfig.
• Определить переменную окружения PKG_CONFIG_PATH так, чтобы она содержала все дополнительные каталоги. Эта стратегия работает неудовлетворительно с точки зрения системы в целом.
16.4. Практика установки
Хорошо знать о том, как собирать и устанавливать программы, но еще полезнее знать о том, когда и где устанавливать собственные пакеты программ. В дистрибутивы Linux стараются уместить максимально возможное количество программ, и вам всегда следует проверять, будет ли лучше, если вы установите пакет ПО самостоятельно. Вот преимущества самостоятельной установки программ:
• можно настроить параметры по умолчанию;
• при установке пакета возникает более ясное представление о том, как его применять;
• вы управляете тем релизом, который запускаете;
• проще создать резервную копию пользовательского пакета;
• проще распространить по сети самоустанавливающиеся пакеты (до тех пор пока архитектура совместима и местоположение для установки изолировано).
Но есть и неудобства:
• на это требуется время;
• пользовательские пакеты не обновляются автоматически. Дистрибутивы обновляют большинство пакетов, не требуя больших трудов. В особенности это относится к пакетам, которые взаимодействуют с сетью, поскольку вам необходимо быть уверенными в том, что применены последние обновления защиты;
• если вы реально не используете пакет, то вы напрасно тратите время;
• есть вероятность неправильной конфигурации пакетов.
Нет особого смысла в установке таких пакетов, как, например, coreutils, который мы собирали в этой главе чуть выше (ls, cat и т. д.), если только вы не собираетесь создать особенную систему. С другой стороны, если вы проявляете живой интерес к сетевым серверам, таким как Apache, то лучший способ получить полный контроль над ним — установить его самостоятельно.
Куда устанавливать. Префикс по умолчанию в утилите GNU Autoconf и многих других пакетах — /usr/local, традиционный каталог для устанавливаемого локального ПО. Обновления операционной системы игнорируют каталог /usr/local, поэтому вы не потеряете ничего из установленного в нем во время обновления ОС. Для небольших локальных программ каталог /usr/local подходит. Единственная проблема заключается в том, что большое количество установленных программ превращается в месиво. Тысячи странных маленьких файлов могут оказаться внутри каталога /usr/local, и у вас не будет ни малейшего понятия о том, откуда они.
Если все настолько вышло из-под контроля, следует создавать собственные пакеты, как рассказано в подразделе 16.3.2.
16.5. Применение исправлений
Большинство изменений в исходном коде программного обеспечения доступно в виде ветвей от исходного кода разработчика (например, репозиторий git). Тем не менее то и дело вам может потребоваться применить исправление к исходному коду, чтобы избавиться от ошибок или добавить новые функции. Вы можете также встретить термин diff, используемый как синоним, поскольку исправление выполняется с помощью команды diff.
Начало исправления может выглядеть таким образом:
—- src/file.c.orig 2015-07-17 14:29:12.000000000 +0100
+++ src/file.c 2015-09-18 10:22:17.000000000 +0100
@@ -2,16 +2,12 @@
Исправления обычно содержат изменения для нескольких файлов. Отыщите строку с тремя дефисами подряд (—-), чтобы понять, какие файлы изменены, и всегда смотрите начало исправления, чтобы определить рекомендуемый рабочий каталог. Обратите внимание на то, что приведенный пример ссылается на файл src/file.c. Следовательно, до применения исправления вы должны перейти в каталог, который содержит каталог src, но не в сам каталог src.
Чтобы применить исправление, запустите команду patch:
$ patch -p0 < patch_file
Если все пройдет успешно, команда patch незаметно завершит свою работу, оставив вам обновленный набор файлов. Однако она может задать вам такой вопрос:
File to patch:
Обычно это означает, что вы находитесь не в том каталоге, но может свидетельствовать также о том, что ваш исходный код не соответствует исходному коду в исправлении. В таком случае вам, вероятно, не повезло: даже если вам удалось бы определить некоторые файлы, подлежащие исправлению, другие остались бы не обновленными, и тогда исходный код не удастся скомпилировать.
В некоторых случаях можно встретить исправление, которое ссылается на версию пакета, например, так:
—- package-3.42/src/file.c.orig 2015-07-17 14:29:12.000000000 +0100
+++ package-3.42/src/file.c 2015-09-18 10:22:17.000000000 +0100
Если номер вашей версии немного отличается (или вы просто переименовали каталог), можно дать указание команде patch, чтобы она обрезала начальные элементы пути. Допустим, например, что вы находитесь в каталоге, который содержит каталог src (как выше). Чтобы команда patch игнорировала часть пути package-3.42/ (то есть отрезала один начальный фрагмент пути), используйте флаг -p1: