Сгенерированный 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@
Другие вопросы по тегам