[英]Correcting the GCC command line ordering using Automake
I have an autotools project that compiles just fine on the Mac, but under Linux (Ubuntu 12.04.1 LTS) the command lines passed to gcc
have the libraries out of order relative to the object files. 我有一个autotools项目,在Mac上编译得很好,但在Linux(Ubuntu 12.04.1 LTS)下,传递给
gcc
的命令行有相对于目标文件的库无序。 For example, autotools generates the following command to compile my code, a single file named test.c
into a binary named test
: 例如,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
This command line fails with: 此命令行失败:
/home/user/glib-test/test.c:4: undefined reference to `g_malloc`
/home/user/glib-test/test.c:5: undefined reference to `g_free`
However, if I compile from the command line and switch it up so the library reference is after the object files it works just fine: 但是,如果我从命令行编译并将其切换,以便库引用位于目标文件之后,它可以正常工作:
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
The challenge is that I can't figure out how to force Autotools to generate the command line in the right order. 挑战在于我无法弄清楚如何强制Autotools以正确的顺序生成命令行。 For the sake of clarity, I've reproduced the simple test case here.
为了清楚起见,我在这里重现了简单的测试用例。 First up is
configure.ac
: 首先是
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
Next is the simple Makefile.am
: 接下来是简单的
Makefile.am
:
CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDFLAGS=$(GLIB_LIBS)
test_SOURCES=test.c
Finally, the source code to this minimal test case, test.c
: 最后,这个最小测试用例的源代码
test.c
:
#include <glib.h>
int main(int argc, char **argv) {
gchar *foo = g_malloc(100);
g_free(foo);
return 0;
}
Compilation is then achieved using the following series of commands: 然后使用以下一系列命令实现编译:
touch NEWS README AUTHORS ChangeLog
aclocal
autoconf
automake --add-missing
./configure
make
I should be clear, I understand why my code won't compile, I'm just wondering how to get automake
to put the libraries at the end of the command line so gcc
will execute and link properly. 我应该清楚,我理解为什么我的代码不会编译,我只是想知道如何让
automake
将库放在命令行的末尾,这样gcc
将正确执行和链接。 It should be noted that gcc
on Mac OS X Lion doesn't seem to have this problem. 应该注意的是,Mac OS X Lion上的
gcc
似乎没有这个问题。
The solution turned out to be the difference between LDFLAGS
and LDADD
. 结果证明
LDFLAGS
和LDADD
之间存在LDADD
。 In short LDFLAGS
is added before the object files on the command line and LDADD
is added afterwards. 简而言之,在命令行上的目标文件和之后添加
LDADD
之前添加LDFLAGS
。 Thus, changing Makefile.am
to the following solved the problem: 因此,将
Makefile.am
更改为以下内容解决了以下问题:
CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDADD=$(GLIB_LIBS)
test_SOURCES=test.c
It only took tracking down a GCC developer at work to solve. 它只追踪了GCC开发人员的工作需要解决。 Also, this example I provided is rather poor because
test
has a defined meaning in some contexts of autotools. 此外,我提供的这个例子相当差,因为
test
在autotools的某些上下文中具有定义的含义。
I solved a similar problem. 我解决了类似的问题。 The ./configure script in question was unable to complete a check for presence of a function due to a missing symbol.
由于缺少符号,有问题的./configure脚本无法检查是否存在函数。 If I added the correct library to
$LDFLAGS
or such like, it was added before the .c
file and the library was ignored. 如果我将正确的库添加到
$LDFLAGS
等,它会在.c
文件之前添加,并且库被忽略。
The names of functions to check are first added to ac_func_list
and then there is a loop in the body of the ./configure
that for each of them calls ac_fn_c_check_func ()
and that in turns calls ac_fn_c_try_link ()
要检查的函数的名称首先被添加到
ac_func_list
,然后在./configure
的主体中有一个循环,每个循环调用ac_fn_c_check_func ()
并且轮流调用ac_fn_c_try_link ()
the checking function ac_fn_c_try_link () uses a command of this pattern: 检查函数ac_fn_c_try_link()使用此模式的命令:
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS \
$LDFLAGS conftest.$ac_ext $LIBS >&5'
$LDADD
is completely ignored here. 这里完全忽略
$LDADD
。 Therefore the only solution here is to add the -l
flags to variable $LIBS
. 因此,这里唯一的解决方案是将
-l
标志添加到变量$LIBS
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.