我使用Ubuntu的清晰的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
他/ Mankchpp
#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 -lfoo
到wah_LDADD
,但说真的,没有的libtool应该为我做自动的? 在`链接的可执行文件的libtool的手册中似乎表明,正是它应该做的。
在任何Debian的机器我使用的发展,我必须手动编译和安装Libtool程序,因为是Debian提供的版本是修补和在打破我构建了一个办法忽略的依赖关系。
如果Ubuntu的版本是相似的,你可能需要安装Libtool程序包从源代码了。
为我工作在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发行版中创建分发包。 我autoreconf的Ubuntu框后,我给你做同样的错误。 显然(根据ADL)Ubuntu的发行版具有一个补丁版本libtool
它设置libtool的脚本变量:
link_all_deplibs=no
我修补的configure
产生的libtool脚本,以取代所有这些实例:
link_all_deplibs=unknown
和一切联系预期。 我想你可以做同样在调用脚本autoreconf
。 或安装的非补丁版本libtool
Ubuntu的主机上。 或修补程序在Ubuntu主机上的修补libtool的。 因此,有关于如何解决它的几个选项。
我想你可以说这是更哲学的差别。 Debian的变化点是为了鼓励用户要明确告知他们依靠什么,这减少了不必要的流失量时依赖内心深处的树得到升级 。
当link_all_deplibs=yes
(未修改libtool的),如果你的程序wah
取决于bar
和bar
依赖于foo
, 则意味着 wah
取决于foo
为好。
当link_all_deplibs=no
(Debian的修改libtool的),如果你的程序wah
取决于bar
和bar
依赖于foo
,那么它是不是意味着 wah
取决于foo
为好。
因此,服用Debian的角度看,这是你的程序错误 : wah
不依赖于foo
凭借这一行:
Bar::Bar( 5 );
在这里,您呼叫的构造Foo::Foo
含蓄。 至于C ++编译器而言,你的程序看起来更像:
Bar::Bar( Foo::Foo( 5 ) );
因此, wah
取决于foo
不只是间接的,而是直接 。 因此,从Debian的角度来看,你应该明确地链接到foo
通过-lfoo
。
特别是,这是不一样的情况,作为libtool的的例子链接可执行文件 。 在该示例中, main.o
不明确依赖libm
,从而-lm
应,原则上,连接时是不必要的main.o
( main.c
不调用cos
直接地)。 也许是为什么libtool的递归链接的原因是周围较老的系统,其中连接体是无法处理间接依赖工作?