Сгенерированный autoconf Makefile не передает флаги для заголовков библиотеки при использовании PKG_CHECK_MODULES
Мой проект зависит от библиотеки (точнее, GTK+), поэтому я добавил следующие конфигурации в свой configure.ac
:
PKG_CHECK_MODULES([GTK], [gtk+-2.0])
AC_SUBST([GTK_CFLAGS])
AC_SUBST([GTK_LIBS])
мой Makefile.am
является:
bin_PROGRAMS = secretary
secretary_SOURCES = secretary.c
В свою очередь, мой secretary.c
как следует:
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(window);
gtk_main();
return 0;
}
Тем не менее, когда я бегу make
(конечно после звонка ./configure
) Я получил эту ошибку:
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT secretary.o -MD -MP -MF .deps/secretary.Tpo -c -o secretary.o secretary.c
secretary.c:1:21: fatal error: gtk/gtk.h: File or directory not found.
Что мне не хватает? Почему autoconf не передает правильные флаги в gcc?
2 ответа
Когда вы используете PKG_CHECK_MODULES, вам необходимо указать флаги в Makefile.am. Самый простой способ - добавить его в AM_LDFLAGS и AM_CPPFLAGS:
AM_LDADD = @GTK_LIBS@
AM_CPPFLAGS = @GTK_CFLAGS@
Если вы хотите быть более конкретным, вместо этого вы можете добавить:
secretary_LDADD = @GTK_LIBS@
secretary_CPPFLAGS = @GTK_CFLAGS@
Вероятно, проще вообще не использовать PKG_CHECK_MODULES и позволить пользователю указывать расположение библиотек с помощью обычного механизма (назначение LDFLAGS или установка библиотек в стандартном месте).
Начиная с предложения @William Pursell, я искал решение. Этот ответ несколько многословен, потому что я чувствую необходимость обосновать, почему я не принимаю этот полезный пост в качестве ответа.
Примечание. Если вам нужны магические линии, просто перейдите к разделу "Решение" в конце.
Попытка предложенного решения
Я попробовал решение Уильяма Перселла, но обнаружил проблему: GCC 4.6.1 особенно требователен при упорядочении некоторых параметров. Поэтому, когда я устанавливаю переменные, как показано ниже:
secretary_CPPFLAGS = @GTK_CFLAGS@ # DOES NOT WORK!
secretary_LDFLAGS = @GTK_LIBS@ # DOES NOT WORK!
Я получил следующее gcc
строка вызова:
gcc -std=gnu99 -g -O2 -pthread -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 \
-lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 \
-lfreetype lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt \
-lglib-2.0 -o secretary secretary-secretary.o
где библиотеки передаются компилятору до .o
код объекта. GCC не принял его и дал мне эту ошибку:
secretary-secretary.o: In function `main':
/home/adam/software/secretary-gtk/secretary.c:4: undefined reference to `gtk_init'
/home/adam/software/secretary-gtk/secretary.c:5: undefined reference to `gtk_window_new'
/home/adam/software/secretary-gtk/secretary.c:6: undefined reference to `gtk_widget_show'
/home/adam/software/secretary-gtk/secretary.c:7: undefined reference to `gtk_main'
После исследования
В поисках решения я обнаружил, что у @uidzer0 была та же проблема, и решил ее - но не опубликовал подробного объяснения... Поэтому я пошел смотреть на его проект. Я посмотрел на его configure.ac
где я нашел использование PKG_CHECK_MODULES
:
PKG_CHECK_MODULES([FUSE], [fuse >= 2.8.3])
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.22.5])
PKG_CHECK_MODULES([GTHREAD], [gthread-2.0])
PKG_CHECK_MODULES([CURL], [libcurl >= 7.16.0])
Поэтому я искал, где сгенерированные переменные (FUSE_LIBS
и т. д.). Я нашел их на src/Makefile.am
файл:
stormfs_CFLAGS = -D_REENTRANT \
-DFUSE_USE_VERSION=26 \
-D_FILE_OFFSET_BITS=64 \
-DSYSCONFDIR=\"${sysconfdir}\" \
${FUSE_CFLAGS} \
${CURL_CFLAGS} \
${GLIB_CFLAGS} \
${GTHREAD_CFLAGS}
stormfs_LDADD = ${LIBS} \
${FUSE_LIBS} \
${CURL_LIBS} \
${GLIB_LIBS} \
${GTHREAD_LIBS}
Решение
Итак, я пришел к выводу, что я должен установить не *_CPPFLAGS
/ *_LDFLAGS
но вместо *_CFLAGS
а также *_LDADD
флаги. Моя итоговая (рабочая) конфигурация тогда:
bin_PROGRAMS = secretary
secretary_SOURCES = secretary.c
secretary_CFLAGS = @GTK_CFLAGS@
secretary_LDADD = @GTK_LIBS@