Участник:Petr-akhlamov/pkg-config
pkg-config — это утилита, которая упрощает сборку программ, особенно тех, которые используют сторонние библиотеки (например, GTK, OpenSSL, и т.п.).
Проще говоря: pkg-config — это помощник сборщика. Он сообщает компилятору, где найти нужные заголовочные файлы (.h) и библиотеки (.so) для какой-либо библиотеки, и какие флаги нужно использовать при компиляции и линковке.
Допустим, у вас программа использует библиотеку gtk+-3.0. Чтобы её скомпилировать, компилятору нужно знать:
- где искать заголовочные файлы: -I /usr/include/gtk-3.0.
- какие библиотеки подключить: -l gtk-3.
Вместо того чтобы прописывать это вручную, вы можете написать:
pkg-config --cflags gtk+-3.0
pkg-config --libs gtk+-3.0
И pkg-config сам подставит правильные пути и флаги.
Как работает pkg-config
pkg-config использует файлы метаданных, названные в честь пакета и имеющие расширение *.pc. В этих файлах хранится информация о библиотеке, включая расположение файлов заголовков и двоичных файлов, а также список зависимых библиотек.
Инструмент запрашивает данные из базы через командную строку и выводит информацию в стандартный вывод. Некоторые данные полезны для программистов, другие — для инструментов сборки, таких как компилятор и компоновщик.
Файлы *.PC
Расширение .pc в контексте сборки Linux относится к конфигурационным файлам инструмента pkg-config, который используется для помощи при компиляции приложения.
Они относятся к пакету pkg-config.
Файлы PKG-Config обеспечивают механизм для хранения различной информации о библиотеках и пакетах. Информация, хранящаяся в файлах .pc, включает в себя компилятор и флаги компилятора, необходимые для использования указанной библиотеки, а также любые другие соответствующие метаданные.
Примеры использования
Некоторые примеры использования pkg-config:
Получение списка библиотек и их зависимостей
Команда:
pkg-config --libs library1 library2 ...
Запрос флагов компиляции и компоновки для указанных библиотек
Команда:
pkg-config --cflags --libs library1 library2 ...
Проверка доступности модуля с помощью опции --exists
Например:
pkg-config --exists foo
Как это используется при сборке RPM-пакетов
1. На этапе сборки (%build):
Пример в Makefile или spec:
gcc $(pkg-config --cflags gtk+-3.0) -o myapp myapp.c $(pkg-config --libs gtk+-3.0)
Или в configure.ac / CMakeLists.txt:
PKG_CHECK_MODULES([GTK], [gtk+-3.0])
2. В .spec файле (BuildRequires):
Чтобы pkg-config мог найти библиотеку, она должна быть установлена вместе с .pc-файлом (обычно в *-devel пакетах).
В .spec нужно указать:
BuildRequires: pkgconfig BuildRequires: pkgconfig(gtk+-3.0)
Это говорит системе сборки, что для компиляции нужен:
- сам pkg-config
- gtk+-3.0.pc (входит в состав gtk3-devel или аналогичного пакета)
Что такое .pc файл?
Это обычный текстовый файл, в котором указано:
- название библиотеки
- её версия
- пути к заголовочным файлам
- параметры компиляции и линковки
Он обычно находится в:
- /usr/lib/pkgconfig/
или
- /usr/lib64/pkgconfig/
или
- /usr/share/pkgconfig/
Пример вывода pkg-config:
$ pkg-config --cflags gtk+-3.0 -I /usr/include/gtk-3.0 -I /usr/include/glib-2.0 ...
$ pkg-config --libs gtk+-3.0 -l gtk-3 -l gdk-3 -l gobject-2.0 ...
Итого:
- pkg-config сообщает компилятору нужные пути и флаги.
- Он облегчает работу с библиотеками.
- В .spec файлах указывается как BuildRequires.
- .pc-файлы — это метаинформация о библиотеках, которую читает pkg-config.
Кто создает эти pc-файлы?
.pc-файлы (файлы для pkg-config) создаются авторами библиотек и включаются в состав их *-devel пакетов (или *-dev в Debian).
Разработчики библиотеки
Когда авторы библиотеки хотят упростить жизнь разработчикам, они создают .pc-файл вручную или с помощью сборочной системы.
Например:
- Autotools (самый частый случай):
В configure.ac/Makefile.am добавляется поддержка pkg-config и автоматически генерируется файл mylib.pc.in, который превращается в mylib.pc.
- CMake:
Используются модули типа CMakePackageConfigHelpers или pkg_check_modules, и .pc-файлы генерируются на этапе сборки.
- Meson:
Meson сам может создавать .pc-файлы при установке (install_data и pkgconfig.generate()).
Где они находятся?
В RPM-пакетах — .pc-файлы обычно идут в составе *-devel:
/usr/lib64/pkgconfig/mylib.pc /usr/share/pkgconfig/mylib.pc
В .spec файле таких пакетов часто можно увидеть:
%files devel
%{_libdir}/pkgconfig/mylib.pc
Пример содержимого .pc файла
Файл libpng.pc:
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64
includedir=${prefix}/include
Name: libpng
Description: Loads and saves PNG files
Version: 1.6.37
Libs: -L${libdir} -lpng16
Cflags: -I${includedir}/libpng16
Пример spec RPM-файла из ALT Linux с примером использования pkg-config
Name: gtk-example Version: 1.0 Release: alt1 Summary: Simple GTK+3 example application License: GPL-2.0-or-later Group: Graphical desktop/GNOME URL: https://example.org Source: %name-%version.tar.gz # Указываем, что для сборки нужен pkg-config и библиотека gtk+-3.0 BuildRequires: pkgconfig BuildRequires: pkgconfig(gtk+-3.0) # Здесь могли бы быть другие зависимости на этапе сборки %description This is a simple application using GTK+3 to demonstrate pkg-config in RPM spec files. %prep %setup %build # Используем флаги, полученные через pkg-config gcc $(pkg-config --cflags gtk+-3.0) -o gtk-example main.c $(pkg-config --libs gtk+-3.0) %install mkdir -p %buildroot%_bindir install -m 755 gtk-example %buildroot%_bindir/ %files %_bindir/gtk-example %changelog * Fri Jul 26 2025 Your Name <you@example.org> 1.0-alt1 - Initial build for ALT Linux
Содержимое main.c (пример программы)
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Hello GTK+3");
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Пояснение ключевых моментов
| Строка | Значение |
|---|---|
| BuildRequires: pkgconfig | Требуется сам инструмент pkg-config |
| BuildRequires: pkgconfig(gtk+-3.0) | Требуется .pc-файл от библиотеки gtk+-3.0, т.е. пакет libgtk+3-devel |
| gcc $(pkg-config ...) | Вставка флагов компиляции и линковки из .pc файла |
Чем он лучше простого прописывания Requires библиотек?
| Подход | Простой (Requires: libgtk+3) | Через pkg-config (BuildRequires: pkgconfig(gtk+-3.0)) |
|---|---|---|
| Проверка наличия заголовков (*.h) | ❌ Нет | ✅ Да |
| Автоматическое определение флагов компиляции и линковки | ❌ Нужно прописывать вручную | ✅ Всё сделает pkg-config |
| Корректная проверка на нужную версию | ⚠️ Сложно (нужно вручную проверять) | ✅ Просто: pkgconfig(libname) >= 1.2 |
| Поддержка альтернативных путей установки | ❌ (не знает, где искать инклуды) | ✅ Учитывает нестандартные пути (includedir, libdir) |
| Работа с виртуальными библиотеками (GLib, GTK, etc) | ❌ | ✅ |
| Совместимость с Autotools/CMake/Meson | Частичная | Отличная |
Пример проблемы без pkg-config
Предположим, вы хотите использовать libpng.
Без pkg-config вы должны:
- вручную указать
BuildRequires: libpng-devel
- в Makefile прописать:
gcc -I/usr/include/libpng16 -lpng16 ...
Что будет, если:
- путь до заголовков изменится?
- имя библиотеки будет другое (libpng12, libpng16)?
→ ❌ Компиляция сломается.
С pkg-config:
- вы пишете:
BuildRequires: pkgconfig(libpng)
- в сборке:
gcc $(pkg-config --cflags libpng) ... $(pkg-config --libs libpng)
→ Всё подставится корректно, независимо от путей, версий и особенностей дистрибутива.
На уровне RPM в ALT Linux и других дистрибутивах реализована поддержка автоматического сопоставления pkgconfig(name) с соответствующими *-devel пакетами.
Например:
BuildRequires: pkgconfig(gtk+-3.0)
найдёт и установит libgtk+3-devel, потому что он содержит файл /usr/lib/pkgconfig/gtk+-3.0.pc.
Источники
- https://en.wikipedia.org/wiki/Pkg-config
- https://docs.fedoraproject.org/en-US/packaging-guidelines/PkgConfigBuildRequires/
- https://unix.stackexchange.com/questions/592437/how-does-pkg-config-work-in-rpm-specfiles
- https://stackoverflow.com/questions/75882877/how-exactly-does-dnf-install-pkgconfigname-syntax-work
- https://docs.oracle.com/cd/E88353_01/html/E37839/pkg-config-1.html
- https://manpages.ubuntu.com/manpages/trusty/man1/pkg-config.1.html
- http://lynchjim.com/doc/pkg-config/pkg-config-guide.html
- https://commandmasters.com/commands/pkg-config-common/
- https://chiark.greenend.org.uk/doc/pkg-config/pkg-config-guide.html
- https://people.freedesktop.org/~dbn/pkg-config-guide.html
- https://ru.linux-console.net/?p=14439