我在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手册部分似乎表明它正是应该做的。
答案 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
取决于bar
而bar
取决于foo
,则隐含 wah
也取决于foo
。
当link_all_deplibs=no
(Debian修改过的libtool)时,如果您的计划wah
取决于bar
而bar
取决于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
,因此在链接-lm
时main.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递归链接的原因是为了解决链接器无法处理间接依赖的旧系统的问题?