【问题标题】:GTK+ gcc: undefined reference to all gtk functions when linkingGTK+ gcc:链接时对所有 gtk 函数的未定义引用
【发布时间】:2013-06-15 13:16:47
【问题描述】:

我正在编写一个带有 GTK+ 的接口,以便使用 XMPP 协议进行聊天。 当我编译它时,我的代码运行良好:

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

但由于我将文件添加到项目中,并且我使用的是 Makefile,因此它不再编译。我猜这个问题来自我的 Makefile。

编译器错误:

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'

生成文件:

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

以及 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);
}

【问题讨论】:

    标签: c linker compiler-errors gtk


    【解决方案1】:

    命令is wrong:这是我继续遇到的一个令人难以置信的常见错误。 gcc 的早期版本对参数顺序不那么挑剔,这传播了错误的想法 pkgconfig --cflags --libs 在每个位置都有效。

    查看this email 以获取有关正确标志排序的信息。简而言之:

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

    【讨论】:

    • 还值得补充的是,即使是单个文件,某些平台也需要在 pkg-config 插入之前列出源文件。 Debian 让我做 gcc pkg-config --blahtest.c,但实际上,MSYS2/mingw-w64 需要 gcc test.c pkg-config --blah ...
    【解决方案2】:

    您尚未在 Makefile 中包含这些库。

    您必须将-L&lt;path to your lib directory-lgtk+-3.0 添加到您的链接器行。

    CLFAGS 不见了……

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

    或这里:

    LDFLAGS         +=      -lexpat
    

    【讨论】:

    • 那是$(shell pkg-config --cflags --libs gtk+-3.0)的工作
    • 但是您的链接器行显示这不会发生。编译器错误的第一行没有显示任何关于库的内容。在您的链接器行中,您没有通过 CFLAGS。
    • 它确实有效,我已经编辑了帖子。我添加了编译的第一行。但我猜它只是链接过程中的一个订单发布者。
    • 就像gcc login_gtk.c $(pkg-config --cflags --libs gtk+-3.0) 确实有效。但是gcc $(pkg-config --cflags --libs gtk+-3.0) login_gtk.c 不起作用。但我不知道如何在我的 Makefile 中管理这种行为
    • 是的,这将是我的下一个猜测,但由于您的行没有显示它,这似乎是一件显而易见的事情。如果它以前有效,那么为什么不看看你的链接器行现在有什么不同呢?
    【解决方案3】:

    我终于通过 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
    

    【讨论】:

    • 这就是我在回答中已经告诉你的,只是给它一个新的变量名。 ;)
    • 我还没这么理解。但实际上我对这种方式并不满意,因为我有很多 c 文件需要用库编译。我不会把它们都这样!太脏了。
    • 您可以编写一个makefile规则,这样您就不必在需要添加新的源文件时对其进行编辑。此外,当包含文件更改时,您可能没有依赖关系。你可以看一下这里,我将我的工作生成文件作为示例发布:stackoverflow.com/questions/16084456/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 2020-12-28
    • 2014-03-04
    相关资源
    最近更新 更多