GTK+ gcc: undefined reference to all gtk functions

2019-04-07 01:07发布

问题:

I'm coding an interface with GTK+ for chat using XMPP protocol. My code worked fine when I compiled it like :

gcc login_gtk.c `pkg-config --cflags --libs gtk+-3.0`

But since I add my file to my project, and I'm using a Makefile, it doesn't compile anymore. I guess the problem comes from my Makefile.

Compiler errors :

gcc -o -W -Wall -Wextra -Werror -g -I./Includes/. -pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12  -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0     -c -o Sources/login_gtk.o Sources/login_gtk.c
gcc -o -W -Wall -Wextra -Werror -g -I./Includes/. -pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12  -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0     -c -o Sources/circular_buffer.o Sources/circular_buffer.c
gcc -o -W -Wall -Wextra -Werror -g -I./Includes/. -pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12  -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0     -c -o Sources/welcome_server.o Sources/welcome_server.c
gcc -o -W -Wall -Wextra -Werror -g -I./Includes/. -pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12  -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0     -c -o Sources/main_loop.o Sources/main_loop.c
gcc -o -W -Wall -Wextra -Werror -g -I./Includes/. -pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12  -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0     -c -o Sources/client_init.o Sources/client_init.c
gcc -o -W -Wall -Wextra -Werror -g -I./Includes/. -pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12  -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0     -c -o Sources/main.o Sources/main.c
gcc -o x2p ./Sources/login_gtk.o ./Sources/circular_buffer.o ./Sources/welcome_server.o ./Sources/main_loop.o ./Sources/client_init.o ./Sources/main.o -lexpat
./Sources/login_gtk.o: In function `login_form':
./Sources/login_gtk.c:10: undefined reference to `gtk_entry_new'
./Sources/login_gtk.c:11: undefined reference to `gtk_entry_get_type'
./Sources/login_gtk.c:11: undefined reference to `g_type_check_instance_cast'
./Sources/login_gtk.c:11: undefined reference to `gtk_entry_set_text'
./Sources/login_gtk.c:12: undefined reference to `gtk_box_get_type'
./Sources/login_gtk.c:12: undefined reference to `g_type_check_instance_cast'
./Sources/login_gtk.c:12: undefined reference to `gtk_box_pack_start'
./Sources/login_gtk.c:13: undefined reference to `gtk_entry_get_type'
./Sources/login_gtk.c:13: undefined reference to `g_type_check_instance_cast'

Makefile:

NAME            =       x2p

SRCS            =                                   \
                    ./Sources/login_gtk.c           \
                    ./Sources/circular_buffer.c     \
                    ./Sources/welcome_server.c      \
                    ./Sources/main_loop.c           \
                    ./Sources/client_init.c         \
                    ./Sources/main.c                \                                                                                                      
OBJS            =       $(SRCS:.c=.o)

CC              =       gcc -o

CFLAGS          =       -W -Wall -Wextra -Werror -g -I./Includes/. $(shell pkg-config --cflags --libs gtk+-3.0)

LDFLAGS         +=      -lexpat

RM              =       rm -f

CAR             =       *\# *~ *core*

all             :       $(NAME)

$(NAME)         :       $(OBJS)
                        $(CC) $(NAME) $(OBJS) $(LDFLAGS)
clean           :
                        $(RM) $(OBJS) $(CAR)

fclean          :       clean
                        $(RM) $(NAME)

re              :       fclean all

And part of login_gtk.c:

#include        <gtk/gtk.h>


void            location_form(GtkWidget *pVBox)
{
  GtkWidget     *pList;

  pList = gtk_combo_box_text_new();
  gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(pList), "LOCATION");
  gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(pList), "WORK");
  gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(pList), "HOME");
  gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(pList), "SCHOOL");
  gtk_combo_box_set_active(GTK_COMBO_BOX(pList), 0);
  gtk_box_pack_start (GTK_BOX(pVBox), pList, FALSE, TRUE, 0);
}

回答1:

The order is wrong: this is an incredibly common mistake I continue to meet. Previous versions of gcc were less picky on the argument order and this spread the wrong idea pkgconfig --cflags --libs works in every position.

Check out this email for info on proper flags ordering. In short:

gcc $(pkg-config --cflags ...) myapp.c $(pkg-config --libs ...)


回答2:

You haven't included the libraries in your Makefile.

You must add -L<path to your lib directory and -lgtk+-3.0 to your linker line.

CLFAGS missing here ...

$(NAME)         :       $(OBJS)
                    $(CC) $(NAME) $(OBJS) $(LDFLAGS)

or here:

LDFLAGS         +=      -lexpat


回答3:

I finally reach to compile by doing this thing the Makefile :

NAME            =       x2p

SRCS            =                                       \
                        ./Sources/circular_buffer.c     \
                        ./Sources/welcome_server.c      \
                        ./Sources/main_loop.c           \
                        ./Sources/client_init.c         \
                        ./Sources/main.c                \                                            

OBJS            =       $(SRCS:.c=.o)

LLFLAGS         =       $(shell pkg-config --cflags --libs gtk+-3.0)

CC              =       gcc

O               =       -o

CFLAGS          =       -W -Wall -Wextra -Werror -g -I./Includes/.


LDFLAGS         +=      -lexpat

RM              =       rm -f

CAR             =       *\# *~ *core*

all             :       $(NAME)

$(NAME)         :       $(OBJS)
                        $(CC) -I./Includes/. ./Sources/login_gtk.c $(LLFLAGS) $(O) $(NAME) $(OBJS) $(LDFLAGS)
clean           :
                        $(RM) $(OBJS) $(CAR)

fclean          :       clean
                        $(RM) $(NAME)

re              :       fclean all