Travis-CI 上的 GTK2 link 错误

GTK2 link error on Travis-CI

我正在开发一个 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 命令中,它似乎确实引用了正确的库。我的系统是 运行ning Debian Wheezy,gcc 版本为 4.7.2。

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

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 输出所示)你可以只使用 [=仅 24=]。

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

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

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