autoconf-generated Makefile does not pass flags for library headers when using PKG_CHECK_MODULES
Asked Answered
C

2

3

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?

Camelot answered 18/4, 2012 at 11:36 Comment(2)
You don't have to AC_SUBST GTK_CFLAGS and GTK_LIBS as PKG_CHECK_MODULES already does that for you.Fritzsche
@JackKelly it's needed for old pkg-config versions (<= 0.24), see section "3.2. Default variables" in autotools.io/pkgconfig/pkg_check_modules.html. I still do build on systems with this ancient pkg-config.Felton
M
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).

Merchandising answered 18/4, 2012 at 15:35 Comment(8)
-1 because your suggestion to not use PKG_CHECK_MODULES is erroneous. You can specify other location by changing PKG_CONFIG_PATH among other ways.Nkrumah
@Nkrumah PKG_CHECK_MODULES has many problems, and the great majority of experienced autotool users (ie the developers posting on the autotool maintenance lists) discourage its use. This particular question is one excellent example of why it is a bad idea: it requires the package maintainer to add additional cruft in the Makefile.am, and it provides zero benefit. Your suggestion to have the user specify PKG_CONFIG_PATH does not address the problem raised in this question, and the build will still fail unless Makefile.am is modified.Merchandising
I am not suggesting a solution, I pointed out what you said that is incorrect or misleading. It would be interesting if you could point me out a discussion on a mailing list where maintainers actually discourage usage of PKG_CHECK_MODULES in favour of having users giving all the flags by hand.Nkrumah
Thank you for your response. Unfortunately, it did not solved my problem immediately (as I explain in my own answer) but was very helpful as a starting point nonetheless.Camelot
BTW, I find the discussion about the disadvantages of PKG_CHECK_MODULES a bit out of place here I did not get what is the problem until now, so I asked another question that may interest you (and @Nkrumah too, of course).Camelot
@Nkrumah Here's an old thread in which I argue in favor of PKG_CHECK_MODULES: lists.gnu.org/archive/html/autoconf/2009-10/msg00132.htmlMerchandising
@Nkrumah Nowhere have I encouraged giving all the flags by hand any more than you have suggested setting PKG_CONFIG_PATH by hand. In fact I would argue heavily that flags should never be set by hand but should be in a config.site. --prefix is the only thing a person should ever by typing as an argument to configure; everything else should come from the environment or a config.site.Merchandising
@William: You can (and perhaps should) use AM_CPPFLAGS = ${GTK_CFLAGS} instead of AM_CPPFLAGS = @GTK_CFLAGS@. That way you can override it a lot easier at make time. PKG_CHECK_MODULES already includes an implicit AC_SUBST call so this works.Breakwater
C
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@
Camelot answered 19/4, 2012 at 2:19 Comment(2)
Arghh. I can't believe I made such a simple error. Of course -l arguments belong in LDADD! Not sure that I can really make this argument, but I will count this as another point against PKG_CHECK_MODULES.Merchandising
Well, in this case you gave the correct answer anyway :) so it will be accepted.Camelot
M
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).

Merchandising answered 18/4, 2012 at 15:35 Comment(8)
-1 because your suggestion to not use PKG_CHECK_MODULES is erroneous. You can specify other location by changing PKG_CONFIG_PATH among other ways.Nkrumah
@Nkrumah PKG_CHECK_MODULES has many problems, and the great majority of experienced autotool users (ie the developers posting on the autotool maintenance lists) discourage its use. This particular question is one excellent example of why it is a bad idea: it requires the package maintainer to add additional cruft in the Makefile.am, and it provides zero benefit. Your suggestion to have the user specify PKG_CONFIG_PATH does not address the problem raised in this question, and the build will still fail unless Makefile.am is modified.Merchandising
I am not suggesting a solution, I pointed out what you said that is incorrect or misleading. It would be interesting if you could point me out a discussion on a mailing list where maintainers actually discourage usage of PKG_CHECK_MODULES in favour of having users giving all the flags by hand.Nkrumah
Thank you for your response. Unfortunately, it did not solved my problem immediately (as I explain in my own answer) but was very helpful as a starting point nonetheless.Camelot
BTW, I find the discussion about the disadvantages of PKG_CHECK_MODULES a bit out of place here I did not get what is the problem until now, so I asked another question that may interest you (and @Nkrumah too, of course).Camelot
@Nkrumah Here's an old thread in which I argue in favor of PKG_CHECK_MODULES: lists.gnu.org/archive/html/autoconf/2009-10/msg00132.htmlMerchandising
@Nkrumah Nowhere have I encouraged giving all the flags by hand any more than you have suggested setting PKG_CONFIG_PATH by hand. In fact I would argue heavily that flags should never be set by hand but should be in a config.site. --prefix is the only thing a person should ever by typing as an argument to configure; everything else should come from the environment or a config.site.Merchandising
@William: You can (and perhaps should) use AM_CPPFLAGS = ${GTK_CFLAGS} instead of AM_CPPFLAGS = @GTK_CFLAGS@. That way you can override it a lot easier at make time. PKG_CHECK_MODULES already includes an implicit AC_SUBST call so this works.Breakwater

© 2022 - 2024 — McMap. All rights reserved.