Разработка программного обеспечения для Linux. Инструментарий
Многие современные программы имеют оконный интерфейс (или просто GUI – Graphical User Interface). Он делает намного удобнее общение с пользователем, позволяет ускорить выполнение ряда рутинных процедур, да и просто GUI – это эстетично и современно. После того, как мы посмотрели, как компилировать и распространять консольные программы, логично было бы проделать то же самое с оконными.
Мы создадим две очень коротких программы. Задача не в том, чтобы научиться создавать программы с оконным интерфейсом (этому будут потом посвящены отдельные руководства), а в том, чтобы продемонстрировать, что их сборка и распространение принципиально не отличаются от того, что мы видели в случае с консольными программами.
Ключевым звеном оконных программ является X-сервер. Он отвечает за прорисовку графических элементов. Программы, имеющие оконный интерфейс должны обращаться к X-серверу. Для обращения к нему служит специальный интерфейс (он называется Xlib). Однако существуют средства, позволяющие избежать непосредственного обращения к низкоуровневому интерфейсу (а работа с ним занимает длительное время). Два наиболее распространённых таких средства – это библиотеки GTK и Qt.
Напишем очень короткую программу с оконным интерфейсом с использованием библиотеки GTK+ 2.0.
Текст её будет выглядеть так (файл main.c).
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gtk/gtk.h>
static void on_destroy (GtkWidget * widget, gpointer data)
{
gtk_main_quit();
}
int main(int argc, char *argv[] )
{
GtkWidget *window;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (on_destroy), NULL);
gtk_widget_show (window);
gtk_main ();
return 0;
}
Чтобы простым способом её скомпилировать, нужно воспользоваться обычным компилятором gcc, сообщив ему, что надо подключить библиотеку GTK+. Для этого мы вызываем утилиту pgk-config. Эта утилита ищет установленные в системе библиотеки и возвращает путь к ним. В данном случае нам нужна библиотека gtk+, что мы и указываем в параметре.
gcc main.c -o gtkdemo `pkg-config --cflags --libs gtk+-2.0`
Теперь давайте подготовим эту программку для распространения.
Создайте каталог проекта. Назовите его gtkdemo. В нём, как обычно, каталог src. В каталоге src – вышеуказанный файл main.c.
В корневом каталоге создайте файл configure.ac
AC_INIT(src/main.c)
AM_CONFIG_HEADER(src/config.h)
AM_INIT_AUTOMAKE(gtkdemo,0.1)
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
PKG_CHECK_MODULES(DEPS, gtk+-2.0 >= 2.2 glib-2.0 >= 2.2)
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)
AC_OUTPUT(Makefile src/Makefile)
Вы, конечно, заметили, что, помимо уже знакомых строк мы сюда включаем директиву PKG_CHECK_MODULES. Эта директива запускает уже знакомую утилиту pkg-config. Путь к заголовочным файлам библиотеки gtk+ сохраняется в переменной DEPS_CFLAGS. Путь к библиотечным файлам – в переменной DEPS_LIBS.
Ещё в корневом каталоге создайте файл Makefile.am
SUBDIRS = src
А в каталоге src – другой файл Makefile.am
bin_PROGRAMS = gtkdemo
gtkdemo_SOURCES = main.c
gtkdemo_LDADD = $(DEPS_LIBS)
AM_CPPFLAGS = $(DEPS_CFLAGS)
Здесь указывается, что адреса, найденные и сохранённые в этих двух переменных, должны быть подключены к проекту.
Всё! Собираем, как обычно.
aclocal
autoconf
touch NEWS README AUTHORS ChangeLog
autoheader
automake -a
./configure
make
make dist
В случае с Qt всё гораздо проще. Вместе с библиотекой Qt поставляется программа qmake, которая берёт на себя роль autoconf, autoheader, automake и других. Только убедитесь, что qmake установлена в вашей системе! Если окажется, что у вас её нет, её придётся устанавливать отдельно: или (лучше всего) из дистрибутива, или (если её нет и в дистрибутиве) из других источников.
Создадим простую программу, аналогичную той, что выше, с использованием Qt. Создайте каталог qtdemo, в нём – каталог src, а в нём – файл main.cpp.
#include <qapplication.h>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QWidget wgt;
QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
wgt.show();
app.setMainWidget(&wgt);
return app.exec();
}
Дальше всё просто. Программа qmake с параметром -project просматривает все файлы с исходным кодом, находящиеся в текущем каталоге, создаёт новый проект (файл с расширением .pro), даёт ему такое же имя, как у текущего каталога, и подключает все найденные файлы к проекту. Далее, командой qmake (без параметров) создаётся Makefile. Итак зайдите в корневой каталог проекта и набирайте:
qmake -project
qmake
make
Далее можете при желании инсталлировать программу.
make install
Или подготовить дистрибутив.
make dist
В этот дистрибутив будет входить и файл проекта (qtdemo.pro). Поэтому пользователи, получив такой пакет не должны запускать configure. Всё, что им надо, это дать следующие команды:
qmake
make
Хотя qmake не требует обязательного присутствия в дистрибутиве файла README, желательно такой файл создать, и описать подробно, как правильно устанавливать программу. Будет неприятно, если пользователь будет источать на вас весь запас бранных слов только из-за того, что у него не установлена библиотека Qt, или из-за того, что его не предупредили, что в данном пакете не надо запускать ./configure.
Курьёзно, что никто вам не запрещает пользоваться утилитой qmake для сборки самых обычных консольных программ, не имеющих никакого отношения к Qt. Например, мы можем взять тот же самый проект kalkul, удалить оттуда все файлы, кроме файлов исходных кодов, зайти туда в консоли, дать команды qmake:
qmake -project
qmake
make
make dist
Если мы возьмём нашу последнюю версию, то там к программе требовалось подключить библиотеку libcalculate. Это делается следующим образом:
qmake -project "LIBS+=-lcalculate"
qmake
make
make dist
Однако не забывайте, что для сборки программы из архива, полученного таким путём, пользователь также должен иметь программу qmake на своём компьютере. Поэтому пользуйтесь такими нестандартными возможностями с большой осторожностью.