Куда мне обратиться, чтобы решить поиск символа / неопределенный символ в проекте automake / autoconf? - PullRequest
2 голосов
/ 21 июля 2009

В одном проекте у меня определены два noinst_PROGRAM. Один из них работает нормально, а другой выдает мне следующее сообщение:

/ дома / Altern-8 / рабочее пространство / 4355 / libgdata / тест / .libs / л-gdatacalendar: ошибка поиска символа: /home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar: неопределенный символ: _ZN5gdata7service7ServiceD1Ev

Я просматривал свои файлы Makefile.am и не могу найти ничего, что пропустил. Приложение правильно компилируется, поэтому я предполагаю, что это означает, что заголовочный файл найден правильно, но по некоторым причинам мой gdata::service::Service не включен в библиотеку src / libgdata.la.

Вполне вероятно, что мое предположение верно? Другие классы, определенные в библиотеке src / libgdata.la, кажутся пригодными для использования. Вывод «make» показывает, что файл Service.cc компилируется правильно ... какие-либо указатели на то, где я должен искать, чтобы убедиться, что он включен в окончательную библиотеку?

EDIT:

Я смог отладить это немного дальше, основываясь на ответах, предоставленных до сих пор.

Деструктор определен в 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

Мой тест / 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 /.

Я расскажу об этом подробнее и, возможно, задам другие вопросы в другой раз.

Ответы [ 2 ]

7 голосов
/ 21 июля 2009

Так как c++filt -n -s gnu-v3 _ZN5gdata7service7ServiceD1Ev дает имя:

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

вам нужно внимательно посмотреть, всегда ли деструктор для этого класса определен, или есть какой-то способ, которым его можно оставить неопределенным (или, на самом деле, определен ли он когда-либо). Или скомпилирован ли исходный файл, содержащий деструктор (почему он не Service.cc?). Некоторый файл, использующий код, ожидает найти деструктор для него, даже если Service.cc не считает, что он необходим.

Другая возможность - ошибка упорядочения библиотек, то есть в строке ссылки перечислены библиотеки в порядке A B C, но они должны быть в порядке B C A или какой-либо другой перестановки, а вы связываете со статическими библиотеками. Обычно это приводит к большому количеству неопределенных символов, если вы связываетесь со статическими библиотеками (но использование общих библиотек скрывает проблемы с упорядочением).

@ Ephemient дал вам несколько хороших советов о том, как найти объектный файл, который ссылается на деструктор. Вы также должны определить, содержит ли Service.o (Service.lo, или .lib/Service.o или другие подобные имена) деструктор - он, скорее всего, не содержит деструктор, учитывая ошибку ссылки.

2 голосов
/ 21 июля 2009

(уже существует проект с именем libgdata , но это, вероятно, не имеет значения.)

$ find -name '*.o' -o -name '*.a' -o -name '*.so' | 
> while read i; do
>     (nm --defined-only $i; nm -D --defined-only $i) 2>/dev/null |
>     grep _ZN5gdata7service7ServiceD1Ev && echo "$i"
> done

Это довольно грубый способ выяснить, в каких объектах (если есть), в которых определен символ _ZN5gdata7service7ServiceD1Ev. (Может быть проще просто найти исходный файл, определяющий gdata::service::Service, если шаблоны не используются .)

$ rm libgdata.la gdatacalendar
$ make

Это грубый способ узнать, что входит в libgdata.la и gdatacalendar. (Но это должно быть довольно очевидно, если взглянуть на (libgdata_la|gdatacalendar)_(SOURCES|LIBADD) в соответствующем Makefile.am.)

Есть ли здесь несоответствие?

...