4

私はubuntulucidでlibtool2.2.6bを使用し、ubuntuでlibtool2.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 / Foo.h

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

foo / Foo.cpp

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

foo / 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 / 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 / Bar.cpp

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

bar / 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;
}

wah / 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のマニュアルのセクションは、まさにそれが実行すべきことを示しているようです。

4

3 に答える 3

5

私が開発に使用するDebianマシンでは、Libtoolを手動でコンパイルしてインストールする必要があります。これは、Debianが提供するバージョンにパッチが適用され、ビルドを壊すような方法で依存関係を無視するためです。

Ubuntuのバージョンが類似している場合は、ソースからLibtoolもインストールすることをお勧めします。

于 2012-08-13T10:07:10.360 に答える
2

哲学の違いだと言えると思います。Debianの変更のポイントは、ユーザーが依存しているものについて明確にすることを奨励することです。これにより、ツリーの深いところにある依存関係がアップグレードされたときに不要なチャーンの量が減ります。

link_all_deplibs=yes(変更されていないlibtool)の場合、プログラムがwahに依存しbarbarに依存している場合はfoo、それも依存していることを意味します。wahfoo

link_all_deplibs=no(Debianの変更されたlibtool)の場合、プログラムがwahに依存しbarbarに依存しているfoo場合、それも依存していることを意味しません。wahfoo

したがって、Debianの観点からすると、これはプログラムでは誤りです。次の行のおかげで依存しwah ます。foo

  Bar::Bar( 5 );

Foo::Fooここでは、のコンストラクターを暗黙的に呼び出しています。C ++コンパイラに関する限り、プログラムは実際には次のようなものです。

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

したがって、間接的にだけでなく、直接的wahにも依存します。したがって、Debianの観点からは、を介して明示的にリンクする必要があります。foofoo-lfoo

特に、これは、実行可能ファイルをリンクするためのlibtoolの例と同じ状況ではありません。その例では、は明示的に依存しないため、 (を直接呼び出さないで)リンクする場合は原則として不要です。おそらく、libtoolが再帰的にリンクする理由は、リンカーが間接的な依存関係を処理できない古いシステムの回避策としてですか?main.olibm-lmmain.omain.ccos

于 2016-11-15T00:36:48.270 に答える
1

Ubuntu 12.04(Precise Pangolin)32ビット、libtool2.4.2で動作します。

私はあなたのMakefileを少しmake dist(もっと)正しく変更する必要がありました:

foo / 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 =

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

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

生成されたlibtoolスクリプトにパッチを適用して、configureこれらすべてのインスタンスを次のように置き換えました。

link_all_deplibs=unknown

そして、すべてが期待どおりにリンクされました。を呼び出すスクリプトでも同じことができると思いますautoreconf。または、パッチが適用されていないバージョンのlibtoolをUbuntuホストにインストールします。または、Ubuntuホストでパッチを適用したlibtoolにパッチを適用します。したがって、それを修正する方法にはいくつかのオプションがあります。

于 2012-08-18T03:58:28.567 に答える