libtool不提供链接的库依赖项

时间:2012-08-03 20:19:23

标签: automake libtool

我在ubuntu lucid上使用libtool 2.2.6b,在ubuntu上使用libtool 2.4.2精确。在清醒我的项目将正确链接。准确无法链接。这是演示我的问题的示例代码;

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

华/ 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

在Lucid,哇链接,在Precise上,它失败了:

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

我可以通过将-L../foo -lfoo添加到wah_LDADD来解决此问题,但实际上,libtool不应该自动为我做这件事吗?关于“链接可执行文件”的libtool手册部分似乎表明它正是应该做的。

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分: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.am

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盒子上自动注册后,我得到了同样的错误。 显然(根据adl),Ubuntu发行版有一个修补版本的libtool,用于设置libtool脚本变量:

link_all_deplibs=no

我修补了configure生成的libtool脚本,用以下内容替换所有这些实例:

link_all_deplibs=unknown

并且所有内容都按预期链接。我想你可以在调用autoreconf的脚本中做同样的事情。或者在Ubuntu主机上安装未修补的libtool版本。或者在Ubuntu主机上修补修补后的libtool。所以有几个选项可以解决它。

答案 2 :(得分: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的角度来看,这是 false 在你的程序中:wah 依靠foo凭借这一行:

  Bar::Bar( 5 );

这里,您隐式调用Foo::Foo的构造函数。就C ++编译器而言,您的程序更像是:

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

因此,wah不仅仅间接依赖foo,而且直接。因此,从Debian的角度来看,您通过foo明确链接到-lfoo

特别是, Linking Executables的libtool示例相同。 在该示例中,main.o并未明确依赖libm,因此在链接-lmmain.o原则上不应该main.c cos class Foo{ get bar(){ return 'foo-bar'; } set bar(n){ this.baz = n * 10; } } let foo = new Foo(); console.log(foo.bar) //foo-bar foo.bar = 7; console.log(foo.baz) //70 直接)。也许libtool递归链接的原因是为了解决链接器无法处理间接依赖的旧系统的问题?