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?

pevik
  • 4,523
  • 3
  • 33
  • 44
brandizzi
  • 26,083
  • 8
  • 103
  • 158
  • 1
    You don't have to `AC_SUBST` `GTK_CFLAGS` and `GTK_LIBS` as `PKG_CHECK_MODULES` already does that for you. – Jack Kelly Aug 03 '12 at 22:16
  • 1
    @JackKelly it's needed for old `pkg-config` versions (<= 0.24), see section "3.2. Default variables" in https://autotools.io/pkgconfig/pkg_check_modules.html. I still do build on systems with this ancient `pkg-config`. – pevik Jan 28 '20 at 19:33

2 Answers2

2

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).

pevik
  • 4,523
  • 3
  • 33
  • 44
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • 6
    -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. – elmarco Apr 18 '12 at 18:38
  • 2
    @elmarco 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. – William Pursell Apr 18 '12 at 18:44
  • 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. – elmarco Apr 19 '12 at 00:48
  • 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. – brandizzi Apr 19 '12 at 02:43
  • 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](http://stackoverflow.com/q/10220946/287976) that may interest you (and @elmarco too, of course). – brandizzi Apr 19 '12 at 02:45
  • 2
    @elmarco Here's an old thread in which I argue in favor of PKG_CHECK_MODULES: http://lists.gnu.org/archive/html/autoconf/2009-10/msg00132.html – William Pursell Apr 19 '12 at 14:26
  • @elmarco 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. – William Pursell Apr 19 '12 at 14:32
  • @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. – jørgensen May 16 '12 at 16:35
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@
Community
  • 1
  • 1
brandizzi
  • 26,083
  • 8
  • 103
  • 158
  • 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. – William Pursell Apr 19 '12 at 14:23
  • Well, in this case you gave the correct answer anyway :) so it will be accepted. – brandizzi Apr 19 '12 at 20:35