2012-08-03 142 views
3

我在ubuntu lucid上使用libtool 2.2.6b,在ubuntu上使用libtool 2.4.2精确。在清晰的我的项目将正确链接。在精确它无法链接。下面是示例代码,演示了我的问题;libtool不提供库链接链接

configure.ac

AC_INIT([ltp], [0.0.1], [someone]) 
AM_INIT_AUTOMAKE 
AC_CONFIG_HEADERS([config.h]) 
AC_CONFIG_MACRO_DIR([.m4]) 
AC_CONFIG_FILES([Makefile foo/Makefile bar/Makefile wah/Makefile]) 
AC_PROG_CXX 
AC_PROG_LIBTOOL 
AM_SANITY_CHECK 
AC_LANG_CPLUSPLUS 
AC_OUTPUT 

Makefile.am

SUBDIRS = foo bar wah 
ACLOCAL_AMFLAGS = -I .m4 

富/ foo.h中

#ifndef FOO_FOO_H_ 
#define FOO_FOO_H_ 
namespace Foo 
{ 
    class Foo 
    { 
    public: 
    Foo(long l); 
    private: 
    long l; 
    }; 
} 
#endif 

富/ Foo.cpp中

#include "foo/Foo.h" 
namespace Foo 
{ 
    Foo::Foo(long l) : l(l) {} 
} 

富/ Makefile.am

lib_LTLIBRARIES = libfoo.la 
libfoo_la_SOURCES = Foo.cpp 
libfoo_la_CPPFLAGS = 
libfoo_la_LDFLAGS = -release 0.0.1 
libfoo_la_LIBADD = 

酒吧/ Bar.h

#ifndef BAR_BAR_H_ 
#define BAR_BAR_H_ 
#include "foo/Foo.h" 
namespace Bar 
{ 
    class Bar 
    { 
    public: 
    Bar(const Foo::Foo & f); 
    private: 
    Foo::Foo f; 
    }; 
} 
#endif 

酒吧/ Bar.cpp

#include "bar/Bar.h" 
namespace Bar 
{ 
    Bar::Bar(const Foo::Foo & f) : f(f) { } 
} 

酒吧/ Makefile.am

lib_LTLIBRARIES = libbar.la 
libbar_la_SOURCES = Bar.cpp 
libbar_la_CPPFLAGS = 
libbar_la_LDFLAGS = -release 0.0.1 
libbar_la_LIBADD = -L../foo -lfoo 

wah/main.cpp

#include "bar/Bar.h" 
int main(int argc, char * argv[]) 
{ 
    Bar::Bar(5); 
    return 0; 
} 

华/ Makefile.am

bin_PROGRAMS = wah 
wah_SOURCES = main.cpp 
wah_CPPFLAGS = 
wah_LDADD = -L../bar -lbar 

在清醒,华环节,对精确,它失败:

wah/main.cpp:5 undefined reference to `Foo::Foo::Foo(long)' 

我可以通过添加-L../foo -lfoowah_LDADD解决这个问题,但真正,是不是libtool应该为我自动做到这一点?关于“链接可执行文件”的libtool手册部分似乎表明,它正是它应该做的。

+0

libfoo_LIBADD,libbar_LIBADD,libfoo_LDFLAGS,libbar_LDFLAGS是什么样的?标志'-ldl -lboost_filesystem -lboost_system'是它们各自库的依赖关系,而不是测试可执行文件。由于这些是共享库(不是静态的),为什么你认为第二行是错误的? – ldav1s 2012-08-08 23:43:05

+0

libfoo_la_LDFLAGS = -release $(PACKAGE_VERSION) libfoo_la_LIBADD = -L $(LIBDIR)-lboost_filesystem -ldl libbar_la_LDFLAGS = -release $(PACKAGE_VERSION) libbar_la_LIBADD = -L $(LIBDIR)-lfoo -lboost_system – CAB 2012-08-10 13:33:10

+0

一个可执行文件的链接与exe_LDADD -lbar链接并运行没有错误。我将不得不更仔细地观察那里发生的事情。所以,我认为单元测试的可执行文件会是类似的。虽然,没有AM_LDADD。但是,从libtool手册; “这看起来太简单了,所以libtool所做的就是将libhello.la转换为./.libs/libhello.a,注意Libtool也记得libhello.la依赖于-lm,所以即使我们没有' t在libtool命令行中指定-lm3 Libtool已将它添加到我们的gcc链接行中。“那么这个exe有什么魔力,但不是单元测试? – CAB 2012-08-10 13:40:28

回答

4

在我用于开发的任何Debian机器上,我必须手动编译和安装Libtool,因为Debian提供的版本已修补并忽略了依赖性,从而破坏了我的构建。

如果Ubuntu的版本类似,您可能也想安装Libtool from source

+1

你可以在补丁上提供更多信息/链接吗?我想了解推动这一变化的原因,并看看我能否找到更多的自动工具风味解决方案。 – CAB 2012-08-13 13:49:36

+2

我认为麻烦的补丁是'link_all_deplibs.patch',因为它将'$ link_all_deplibs'设置为'no'。邮件http://lists.gnu.org/archive/html/libtool/2007-09/msg00017.html给出了一个例子。 – adl 2012-08-13 15:09:39

+1

是的,使用香草'libtoolize'修复了我的构建问题。在Ubuntu 12.04上运行'libtoolize'后,我遇到了很多间接库依赖的问题。特别是,没有在二进制库文件中反映的库依赖性(但只通过头文件中的内联函数)。 Debian/Ubuntu的人们可以决定如何严重破坏Libtool是不错的。 – 2013-03-07 21:19:36

1

适用于Ubuntu 12.04(精准穿山甲)32位,libtool 2.4.2。

我确实有几分正确地改变你的Makefile来make dist(更多):

富/ Makefile.am:

lib_LTLIBRARIES = libfoo.la 
libfoo_la_SOURCES = Foo.cpp Foo.h 
libfoo_la_CPPFLAGS = 
libfoo_la_LDFLAGS = -release 0.0.1 
libfoo_la_LIBADD = 

酒吧/ Makefile.am:

lib_LTLIBRARIES = libbar.la 
libbar_la_SOURCES = Bar.cpp Bar.h 
libbar_la_CPPFLAGS = 
libbar_la_LDFLAGS = -release 0.0.1 
libbar_la_LIBADD = -L../foo -lfoo 

华/ Makefile文件。我

bin_PROGRAMS = wah 
wah_SOURCES = main.cpp ../bar/Bar.h 
wah_CPPFLAGS = 
wah_LDADD = -L../bar -lbar 

下面是它的链接main.cpp

make[2]: Entering directory `/xxx/ltp-0.0.1/wah' 
g++ -DHAVE_CONFIG_H -I. -I..  -g -O2 -MT wah-main.o -MD -MP -MF .deps/wah-main.Tpo -c -o wah-main.o `test -f 'main.cpp' || echo './'`main.cpp 
mv -f .deps/wah-main.Tpo .deps/wah-main.Po 
/bin/bash ../libtool --tag=CXX --mode=link g++ -g -O2 -o wah wah-main.o -L../bar -lbar 
libtool: link: g++ -g -O2 -o .libs/wah wah-main.o -L../bar /xxx/ltp-0.0.1/bar/.libs/libbar.so -L../foo /xxx/ltp-0.0.1/foo/.libs/libfoo.so 

不libtool的应该为我做自动的?

是的,至少在非Ubuntu发行版上创建分发tarball时是这样。在Ubuntu盒子上进行autoreconf后,我会遇到同样的错误。 显然(根据ADL)Ubuntu的发行具有libtool一个补丁版本,其设置libtool的脚本变量:

link_all_deplibs=no 

我修补的configure产生libtool的脚本,以取代所有这些实例:

link_all_deplibs=unknown 

和一切按预期链接。我想你可以在调用autoreconf的脚本中做同样的事情。或者在Ubuntu主机上安装libtool的未修补版本。或者在Ubuntu主机上修补修补过的libtool。所以有几个选项可以解决这个问题。

1

我想你可以说这是在理念更多的差别。 Debian的变化点是为了鼓励用户要明确告知他们依赖于什么,这reduces the amount of unnecessary churn when dependencies deep down the tree get upgraded

link_all_deplibs=yes(未修改libtool的),如果你的程序wah取决于barbar取决于foo,则暗示wah取决于foo为好。

link_all_deplibs=no(Debian的修改libtool的),如果你的程序wah取决于barbar取决于foo,那么它是不是暗示wah取决于foo为好。

所以,服用Debian的角度看,这是你的程序wah确实取决于foo凭借这一行:

Bar::Bar(5); 

在这里,你是隐式调用的Foo::Foo构造。至于C++编译器而言,你的程序看起来更像:

Bar::Bar(Foo::Foo(5)); 

因此,wah取决于foo不只是间接的,但直接。因此,从Debian的角度来看,你是应该明确通过-lfoo链接到foo

特别是,这是而不是与libtool的示例Linking Executables相同的情况。在该示例中,main.o没有明确依赖于libm,因此-lm原则上在连接main.omain.c不直接呼叫cos)时应该是不必要的。也许libtool链接递归的原因是为了解决链接器无法处理间接依赖关系的旧系统?