使用Automake更正GCC命令行顺序

Pri*_*ett 9 linux automake gcc autotools

我有一个autotools项目,可以在Mac上编译得很好,但在Linux(Ubuntu 12.04.1 LTS)下,命令行传递给gcc库相对于目标文件乱序.例如,autotools生成以下命令来编译我的代码,一个名为test.c二进制文件的文件命名为test:

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -lglib-2.0 -o test test-test.o
Run Code Online (Sandbox Code Playgroud)

此命令行失败:

/home/user/glib-test/test.c:4: undefined reference to `g_malloc`
/home/user/glib-test/test.c:5: undefined reference to `g_free`
Run Code Online (Sandbox Code Playgroud)

但是,如果我从命令行编译并将其切换,以便库引用位于目标文件之后,它可以正常工作:

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -o test test-test.o -lglib-2.0
Run Code Online (Sandbox Code Playgroud)

挑战在于我无法弄清楚如何强制Autotools以正确的顺序生成命令行.为了清楚起见,我在这里重现了简单的测试用例.首先是configure.ac:

dnl Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)
AC_INIT(glib-test, 1.0)

AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE()

AC_PROG_CC
AM_PROG_CC_C_O
PKG_CHECK_MODULES(GLIB, glib-2.0 > 2.0)
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
Run Code Online (Sandbox Code Playgroud)

接下来很简单Makefile.am:

CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDFLAGS=$(GLIB_LIBS)
test_SOURCES=test.c
Run Code Online (Sandbox Code Playgroud)

最后,这个最小测试用例的源代码,test.c:

#include <glib.h>

int main(int argc, char **argv) {
    gchar *foo = g_malloc(100);
    g_free(foo);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后使用以下一系列命令实现编译:

touch NEWS README AUTHORS ChangeLog
aclocal
autoconf
automake --add-missing
./configure
make
Run Code Online (Sandbox Code Playgroud)

我应该清楚,我理解为什么我的代码不会编译,我只是想知道如何automake将库放在命令行的末尾,以便gcc正确执行和链接.应该注意的是,gcc在Mac OS X Lion上似乎没有这个问题.

Pri*_*ett 15

该解决方案被证明是之间的差值LDFLAGSLDADD.简而言之LDFLAGS,在命令行上的目标文件之前LDADD添加并在之后添加.因此,Makefile.am改为以下解决了这个问题:

CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDADD=$(GLIB_LIBS)
test_SOURCES=test.c
Run Code Online (Sandbox Code Playgroud)

它只追踪了GCC开发人员的工作需要解决.此外,我提供的这个例子相当差,因为test在autotools的某些上下文中具有定义的含义.

  • @William:Automake doc说"`PROG_LDADD`不适合传递特定于程序的链接器标志(**除了**,用于`-l`,`-L`,`-dlopen`和`-dlpreopen`)." (3认同)
  • 请注意,automake文档清楚地指出LDADD是`-l`标志的错误位置.虽然这有效,但闻起来并不合适. (2认同)