У меня есть довольно странная ошибка соединения в проекте, который автоделает использование. То, что я делаю, кажется довольно простым из руководства, таким образом, я действительно задаюсь вопросом, что я могу, делая неправильно...
Мой проект имеет три папки:
Каждая из библиотек компилируется с Makefile.am как это:
noinst_LIBRARIES=libube-common.a
libube_common_a_SOURCES=gettext.h lua_helper.hpp \
silent_ostream.hpp \
logging.hpp logging.cpp \
logger_interface.hpp \
... etc ...
AM_CPPFLAGS=-DSRCDIR=\"${srcdir}\" \
-DLUADIR=\"${luadir}\" \
-Wall -Werror \
-I$(srcdir)/../../include \
$(LUA_INCLUDE) \
$(BOOST_CPPFLAGS)
Это приводит к различным объектам, создаваемым со строкой как:
g++ -DHAVE_CONFIG_H -I. -I../../../../../src/common -I../.. -DSRCDIR=\"../../../../../src/common\" -DLUADIR=\"\" -Wall -Werror -I../../../../../src/common/../../include -I/usr/include/lua5.1 -I/usr/include -g -O2 -MT logging.o -MD -MP -MF .deps/logging.Tpo -c -o logging.o ../../../../../src/common/logging.cpp
И все они помещаются в библиотеку с:
ar cru libube-common.a logging.o prefix_resource_resolver.o stat_file_checker.o
ranlib libube-common.a
Все это кажется хорошим и хорошо, я могу, даже связал некоторые небольшие тестовые программы против библиотеки (в том же make-файле)
Затем в Makefile.am моей основной программы я попросил связываться против местных библиотек:
ube_LDADD=../common/libube-common.a \
../engine/libube-engine.a \
libube-client.a \
... other libs ...
И это - то, где я получаю ошибки как это:
g++ -g -O2 -o ube ube.o ../common/libube-common.a ../engine/libube-engine.a libube- client.a -L/usr/include/lua5.1/lib -llua5.1 -lm -ldl -L/usr/lib -lSDL -lSDL_image -lpng -ltiff -ljpeg -lz -lSDL_ttf -lfreetype -lSDL_mixer -lSDL_mixer -lSDL_ttf -lSDL_image
libube-client.a(game_loop.o): In function `Logging::debug_ostream(std::basic_string, std::allocator >)':
(...) logging.hpp:54: undefined reference to `Logging::get_ostream(LogLevel::Level, std::basic_string, std::allocator >)'
(...)logging.hpp:54: undefined reference to `Logging::get_ostream(LogLevel::Level, std::basic_string, std::allocator >)'
Сначала я, хотя это было из-за некоторых статических символов, но я также получаю проблему с нестатическими.
Я проверил, что сгенерированный освобождает, и это, кажется, содержит символ правильно:
~/prj/ube/builds/linux/current/src/common$ nm -C libube-common.a | grep logging.o -C 20
logging.o:
00000010 t global constructors keyed to _ZN7Logging15disable_loggingEv
00000000 V guard variable for Logging::get_instance()::s_local_instance
000000b0 T Logging::get_ostream(LogLevel::Level, std::string)
00000000 T Logging::disable_logging()
00000040 T Logging::is_category_enabled(LogLevel::Level, std::string&)
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
00000000 b std::__ioinit
U __cxa_atexit
U __dso_handle
U __gxx_personality_v0
Единственная фиксация к ссылке explicitely против моих.o файлов (путем добавления их к ube_LDADD строке..., но такой игнорирует идею пользоваться библиотекой!!)
Я, кажется, следовал руководству: http://www.gnu.org/software/hello/manual/automake/Linking.html#Linking
Но ovbiously я испортил где-нибудь, таким образом, любая идея приветствуется!!
Спасибо
PH
РЕДАКТИРОВАНИЕ: библиотека сам по себе, кажется, работает, это, кажется, связывающаяся проблема. Я могу связать свои программы тестовых сценариев agaist их. Вот то, что я делаю:
В папке, src/common/tests, существует основное, названное распространенным-tests.cpp, который выполняет модульные тесты; мусорное ведро общих тестов связано против библиотеки libube-common.a (этому только нужны объекты, которые являются в lib, так как это - модульные тесты),
# There is one program that aggreatates all tests cases
check_PROGRAMS = common-tests
common_tests_SOURCES= tests/common_tests.cpp \
tests/prefix_resource_resolver_test.cpp \
tests/mock_file_checker.hpp \
tests/stat_file_checker_test.cpp
# The program needs to be compiled against the local lib
common_tests_LDADD=libube-common.a -L$(top_srcdir)/lib -lgtest -lgmock -llua -ldl
# This means common-tests is run when using 'make check'.
TESTS = common-tests
Когда выполнение осуществляет проверку, тестовая программа компилируется этот путь:
g++ -g -O2 -o common-tests common_tests.o prefix_resource_resolver_test.o stat_file_checker_test.o libube-common.a -L../../../../../lib -lgtest -lgmock -llua -ldl -lSDL_mixer -lSDL_ttf -lSDL_image
И вещи работают отлично. Единственной разницей я вижу это, является в этом случае библиотека, прямо рядом с исполняемым файлом для соединения... это могло действительно иметь какое-либо значение?
Кроме того, я пытался использовать опции как-Wl, - целый архив, но он не помог (плюс я не знаю, как добавить их к Автоделанию - сгенерированная строка...),
Это, скорее всего, в библиотеке по вопросам упорядочения - тем более «обычная» библиотека, а более поздняя она должна происходить в окончательной линии связи. В частности, GNU LD читает библиотеки для символов точно один раз , а затем отбрасывает все другие символы из библиотеки, прежде чем перейти к следующей библиотечной инструкции. Есть различные решения (см. Страницу «Человек» для «LD»), но самое простое - заменить линии в вашем Makefile.am, чтобы поставить Libube-Common.a после клиент и либус.
Обратите внимание, что DARWIN LD не имеет это поведение, он по умолчанию сохраняет все символы библиотеки (что потенциально использует гораздо больше памяти во время ссылки).