【问题标题】:GTK2 link error on Travis-CITravis-CI 上的 GTK2 链接错误
【发布时间】:2015-04-14 07:40:36
【问题描述】:

我正在开发一个 xfce4 插件,我正在尝试使用 Travis-CI。我在我的根目录中写了一个 Makefile.am,如下所示:

SUBDIRS = src
dist_doc_DATA = README.md

因此,在我的 src 目录中有一个像这样的 Makefile.am:

bin_PROGRAMS = visualaudio
visualaudio_SOURCES = visualaudio.c
visualaudio_CFLAGS = $(GTK_CFLAGS) $(LIBXFCE4PANEL_CFLAGS) -W -Wall
visualaudio_LDFLAGS = $(GTK_LIBS) $(LIBXFCE4PANEL_LIBS)

我正在使用以下命令来配置和构建项目:

xdt-autogen && make && make test

这会导致以下运行:

Preparing package directory     /home/travis/build/alex/visualaudio...
Running aclocal-1.11   -I /usr/share/xfce4/dev-tools/m4macros -I /usr/share/xfce4/dev-tools/m4macros...
Running autoheader...
Running automake-1.11 --force-missing --add-missing --copy --gnu...
Running autoconf...
Running /home/travis/build/alex/visualaudio/configure --enable-maintainer-mode ...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether to enable maintainer-specific portions of Makefiles...  yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for gtk+-2.0 >= 2.6.0... 2.24.10
checking GTK_CFLAGS... -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12  
checking GTK_LIBS... -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 -lglib-2.0  
checking for pkg-config... (cached) /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for libxfce4panel-1.0 >= 4.8.0... 4.8.6
checking LIBXFCE4PANEL_CFLAGS... -pthread -I/usr/include/xfce4/libxfce4panel-1.0 -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/xfce4  
checking LIBXFCE4PANEL_LIBS... -Wl,--export-dynamic -pthread -lxfce4panel-1.0 -lgtk-x11-2.0 -lgmodule-2.0 -lrt -lxfce4util -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 -lglib-2.0  
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands
Now type "make" to compile.
(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash   /home/travis/build/alex/visualaudio/missing --run autoheader)
rm -f stamp-h1
touch config.h.in
cd . && /bin/bash ./config.status config.h
config.status: creating config.h
config.status: config.h is unchanged
make  all-recursive
make[1]: Entering directory `/home/travis/build/alex/visualaudio'
Making all in src
make[2]: Entering directory `/home/travis/build/alex/visualaudio/src'
gcc -DHAVE_CONFIG_H -I. -I..    -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12   -pthread -I/usr/include/xfce4/libxfce4panel-1.0 -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/xfce4   -W -Wall -g -O2 -MT visualaudio-visualaudio.o -MD -MP -MF .deps/visualaudio-visualaudio.Tpo -c -o visualaudio-visualaudio.o `test -f 'visualaudio.c' ||     echo './'`visualaudio.c
mv -f .deps/visualaudio-visualaudio.Tpo .deps/visualaudio-visualaudio.Po
gcc -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12   -pthread -I/usr/include/xfce4/libxfce4panel-1.0 -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/xfce4   -W -Wall -g -O2 -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 -lglib-2.0   -Wl,--export-dynamic -pthread -lxfce4panel-1.0 -lgtk-x11-2.0 -lgmodule-2.0 -lrt -lxfce4util -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 -lglib-2.0    -o visualaudio visualaudio- visualaudio.o  
visualaudio-visualaudio.o: In function `on_window_destroy_event':
/home/travis/build/alex/visualaudio/src/visualaudio.c:6: undefined reference to `gtk_main_quit'
visualaudio-visualaudio.o: In function `main':
/home/travis/build/alex/visualaudio/src/visualaudio.c:12: undefined reference to `gtk_init'
/home/travis/build/alex/visualaudio/src/visualaudio.c:14: undefined reference to `gtk_window_new'
/home/travis/build/alex/visualaudio/src/visualaudio.c:15: undefined reference to `gtk_widget_show'
/home/travis/build/alex/visualaudio/src/visualaudio.c:17: undefined reference to `gtk_window_get_type'
/home/travis/build/alex/visualaudio/src/visualaudio.c:17: undefined reference to `g_type_check_instance_cast'
/home/travis/build/alex/visualaudio/src/visualaudio.c:17: undefined reference to `gtk_window_set_decorated'
/home/travis/build/alex/visualaudio/src/visualaudio.c:20: undefined reference to `g_type_check_instance_cast'
/home/travis/build/alex/visualaudio/src/visualaudio.c:20: undefined reference to `g_signal_connect_data'
/home/travis/build/alex/visualaudio/src/visualaudio.c:22: undefined reference to `gtk_main'
collect2: ld returned 1 exit status
make[2]: *** [visualaudio] Error 1
make[2]: Leaving directory `/home/travis/build/alex/visualaudio/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/travis/build/alex/visualaudio'
make: *** [all] Error 2

在本地,这会在没有任何警告的情况下成功。那是-W和-Wall。在 Travis-CI 上,似乎没有链接正确的库,即使在 gcc 命令中,它似乎确实引用了正确的库。我的系统正在运行 gcc 版本 4.7.2 的 Debian Wheezy。

编辑: 刚刚将 Travis-CI 上的 C 编译器更改为 Clang。一切都成功编译和链接。与 Debian 相比,我猜这与 Ubuntu 上较新版本的 GCC 有关。也许是旗帜的顺序?

【问题讨论】:

标签: c linker gtk travis-ci xfce


【解决方案1】:

Automake 手册将相关信息隐藏在其错综复杂的结构中,但是……您在滥用 LDFLAGS。

通过仔细阅读 the section 关于 automake 变量的内容,您会发现:

  • LIBADD 应该包含额外的对象和 libtool 库(即 .la 文件)以添加到 库;
  • LDADD 应该包含额外的对象、libtool 库和 -l、-L、-dlopen 和 -dlpreopen 标志以添加到程序;
  • LDFLAGS 应该包含其他所有内容。

此外,您应该注意对象、库、-l 和 -L 标志的顺序很重要。这不是gcc 痒,而是由c99 standard 决定的。这可能意味着 clang 构建成功,因为它不是 C99 模式。

我还怀疑 libxfce4panel 已经依赖于 GTK+,如果您通过 pkg-config 获得标志(正如您的 configure 输出所示),您可以只使用 libxfce4panel。

最后我认为正确的 Makefile.am 可能是:

bin_PROGRAMS = visualaudio
visualaudio_CFLAGS = $(LIBXFCE4PANEL_CFLAGS)
visualaudio_LDADD = $(LIBXFCE4PANEL_LIBS)

visualaudio.c 作为源文件是隐含的。额外的标志应该由外部通过配置添加,而不是硬编码到 makefile 中,例如在您的.travis.yml 中,您可以使用./configure CFLAGS='-W -Wall'。

【讨论】:

  • 很好的答案,写得很好,解释也很好。特别感谢 automake 手册页的链接。明天我会试一试,如果一切顺利的话——我希望会是这样——我会把你的答案标记为正确的!
  • 不出所料,一切顺利。非常感谢您的帮助!
  • @Alex 欢迎您。我必须补充一点,我不确定我的最后一个理论,即如果 a 对 b 有依赖性,你可以只使用 a。越想越觉得不对。
  • 我使用的工具集确实如此(xdt,尤其是 xdt-autogen,我相信它在内部使用 pkg-config)。我已经将它完全公开了,但由于 libxfce4 依赖于 GTK2,所以将它排除在 Makefile.am 之外。
猜你喜欢
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2013-12-02
  • 2014-04-02
相关资源
最近更新 更多