2

1 つのプロジェクトで、2 つnoinst_PROGRAMの が定義されています。そのうちの 1 つは問題なく動作しますが、もう 1 つは次のメッセージを表示しています。

/home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar: シンボル検索エラー: /home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar: 未定義のシンボル: _ZN5gdata7service7ServiceD1Ev

Makefile.am ファイルを調べましたが、見逃したものは見つかりません。アプリケーションは正しくコンパイルされるので、これはヘッダー ファイルが正しく検出されたことを意味すると推測していますが、何らかの理由で mygdata::service::Serviceが src/libgdata.la ライブラリに含まれていません。

私の仮定が正しい可能性はありますか?src/libgdata.la ライブラリで定義されている他のクラスは使用できるようです。「make」の出力は、Service.cc ファイルが正しくコンパイルされていることを示しています...最終的なライブラリに含まれていることを確認するためにどこを参照すればよいですか?

編集:

これまでに提供された回答に基づいて、これをさらにデバッグすることができました。

デストラクタは Service.cc で定義されています。ヘッダー ファイルでデストラクタに本文を指定すると、すべて正常に動作します。

// In Service.h
~Service() {}

// In Service.cc
// Service::~Service() {}

デストラクタが「機能する」ようになったので、Service.cc で定義されている他のメソッドが見つからないことに遭遇しました。

@ephemient の方法を使用すると、これらのシンボルが実際にライブラリに含まれているように見えます。または、出力を間違って読んでいますか?

000000e0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_
000000a0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b
./src/.libs/libgdata.a
000240d0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_
00024090 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b
000240d0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_
00024090 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b
./src/.libs/libgdata.so
00000080 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_
00000070 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b
./src//gdata/service/libgdata__gdata_service_la-Service.o
000000e0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_
000000a0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b
./src//gdata/service/.libs/libgdata__gdata_service.a
000000e0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_
000000a0 T _ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_b
./src//gdata/service/.libs/libgdata__gdata_service_la-Service.o

私の src/Makefile.am は次のようになります。

SUBDIRS = gdata

lib_LTLIBRARIES = libgdata.la

libgdata_la_SOURCES = 

libgdata_la_LIBADD = \
    gdata/client/libgdata_gdata_client.la \
    gdata/data/libgdata_gdata_data.la \
    gdata/data/youtube/libgdata_gdata_data_youtube.la \
    gdata/util/libgdata_gdata_util.la \
    gdata/service/libgdata_gdata_service.la \
    gdata/service/calendar/libgdata_gdata_service_calendar.la

私の src/gdata/service/Makefile.am は次のようになります。

SUBDIRS = calendar

noinst_LTLIBRARIES = libgdata_gdata_service.la

libgdata_gdata_service_ladir = \
    $(includedir)/gdata/service

libgdata_gdata_service_la_SOURCES = \
    Service.cc

libgdata_gdata_service_la_HEADERS = \
    Service.h

私の test/Makefile.am は次のようになります。

INCLUDES = -I$(top_srcdir)/src/ -I$(top_srcdir)/test/

LDADD = ../src/libgdata.la

TESTS = check_bare

noinst_PROGRAMS = gdatacalendar gdatayoutube $(TESTS)

check_bare_SOURCES = check_bare.cc

gdatacalendar_SOURCES = gdatacalendar.cc

gdatayoutube_SOURCES = gdatayoutube.cc

gdatayoutube は問題なく動作します。サービス( gdata/client/libgdata_gdata_client.la )の代わりにクライアントディレクトリのコードを使用するのは古いコードです...クライアントがサービスからセットアップされる方法に違いはありません。:-/

**編集#2:##

これがどのように起こったのかはわかりませんが、問題は見つかったと思います。テスト アプリは、src/.

私はこれをさらに調査し、別の機会に他の質問をするかもしれません。

4

2 に答える 2

7

名前が得られるのでc++filt -n -s gnu-v3 _ZN5gdata7service7ServiceD1Ev

gdata::service::Service::~Service()

そのクラスのデストラクタが常に定義されているかどうか、または定義されていないままにしておく方法があるかどうか (または、実際に定義されているかどうか) をよく調べる必要があります。または、デストラクタを含むソース ファイルService.ccがコンパイルされているかどうか (そうでないのはなぜですか?)。Service.ccコードを使用する一部のファイルは、デストラクタが必要であるとは考えていなくても、そのデストラクタを見つけることを期待しています。

もう 1 つの可能性は、ライブラリの順序付けエラーです。つまり、リンク行にはライブラリが ABC の順序でリストされていますが、BCA の順序またはその他の順列である必要があり、静的ライブラリとリンクしています。通常、静的ライブラリとリンクしている場合、未定義のシンボルが大量に発生します (ただし、共有ライブラリを使用すると、順序付けの問題が隠されます)。

@Ephemient は、デストラクタを参照するオブジェクト ファイルを見つける方法について、いくつかの適切な指針を提供してくれました。Service.oまた、 ( Service.lo、または他の類似の名前) にデストラクタが含まれているかどうかも判断する必要があり.lib/Service.oます。リンク エラーを考えると、デストラクタが含まれていない可能性が高くなります。

于 2009-07-21T01:48:05.263 に答える
2

(すでにlibgdataという名前の既存のプロジェクトがありますが、それはおそらく関係ありません。)

$ find -name '*.o' -o -name '*.a' -o -name '*.so' |
> 読みながら私; 行う
> (nm --defined-only $i; nm -D --defined-only $i) 2>/dev/null |
> grep _ZN5gdata7service7ServiceD1Ev && echo "$i"
>完了

_ZN5gdata7service7ServiceD1Evこれは、シンボルが定義されているオブジェクト (存在する場合) を発見するためのかなり強引な方法gdata::service::Serviceです。

$ rm libgdata.la gdatacalendar
$メイク

libgdata.laこれは、とに含まれているものを発見する力ずくの方法gdatacalendarです。(libgdata_la|gdatacalendar)_(SOURCES|LIBADD)(しかし、適切なを見れば明らかなはずMakefile.amです。)

ここにミスマッチはありますか?

于 2009-07-21T01:47:20.520 に答える