2012-08-03 77 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鏈接遞歸的原因是爲了解決鏈接器無法處理間接依賴關係的舊系統?