问题
My project depends upon a library (more precisely, GTK+) so I added the following configurations in my configure.ac
:
PKG_CHECK_MODULES([GTK], [gtk+-2.0])
AC_SUBST([GTK_CFLAGS])
AC_SUBST([GTK_LIBS])
My Makefile.am
is:
bin_PROGRAMS = secretary
secretary_SOURCES = secretary.c
For its turn, my secretary.c
is as follows:
#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;
}
However, when I run make
(of course, after calling ./configure
) I got this error:
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.
What am I missing? Why does autoconf not pass the correct flags to gcc?
回答1:
When you use PKG_CHECK_MODULES, you need to specify the flags in Makefile.am. The easiest way is to add it to AM_LDFLAGS and AM_CPPFLAGS:
AM_LDADD = @GTK_LIBS@
AM_CPPFLAGS = @GTK_CFLAGS@
If you want to be more specific, you can instead add:
secretary_LDADD = @GTK_LIBS@
secretary_CPPFLAGS = @GTK_CFLAGS@
It is probably easier to not use PKG_CHECK_MODULES at all and let the user specify the location of the libraries through the usual mechanism (assigning LDFLAGS or installing the libraries in a standard location).
回答2:
Starting from @William Pursell suggestion, I looked for a solution. This answer is somewhat verbose because I feel the need to justify why I am not accepting this helpful post as the answer.
Note: If you are looking for some magic lines, just skip to "The Solution" section at the end.
Trying the proposed solution
I tried William Pursell solution but found a problem: GCC 4.6.1 is specially demanding when dealing with ordering of some parameters. So when I set the variables as below:
secretary_CPPFLAGS = @GTK_CFLAGS@ # DOES NOT WORK!
secretary_LDFLAGS = @GTK_LIBS@ # DOES NOT WORK!
I got the following gcc
invocation line:
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
where the libraries are passed to the compiler before the .o
object code. GCC did not accept it and gave me this error:
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'
Following research
Looking for a solution, I found that @uidzer0 had the same problem and solved it - but did not post a comprehensive explanation... So I went for looking at his project. I looked at its configure.ac where I found the usage of 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])
So I looked for where the generated variables (FUSE_LIBS
etc.) were used. I found them at the src/Makefile.am file:
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}
The solution
So I conclude I should set not the *_CPPFLAGS
/ *_LDFLAGS
but instead the *_CFLAGS
and *_LDADD
flags. My resulting (working) configuration then is:
bin_PROGRAMS = secretary
secretary_SOURCES = secretary.c
secretary_CFLAGS = @GTK_CFLAGS@
secretary_LDADD = @GTK_LIBS@
来源:https://stackoverflow.com/questions/10208523/autoconf-generated-makefile-does-not-pass-flags-for-library-headers-when-using-p