Autoconf: ошибка компоновщика при связывании с пользовательской библиотекой - PullRequest
1 голос
/ 24 февраля 2012

1) У меня есть проект, содержащий общую библиотеку, которая ссылается на некоторые иностранные библиотеки (а именно gcrypt, gpg-error, z и ssh2). Давайте назовем это "mylib". Эта библиотека прекрасно собирается, и я вижу, как libtool правильно связывает зависимости.

libtool: link: ppc-linux-gcc -shared  -fPIC -DPIC  .libs/mylib1.o .libs/mylib2.o .libs/mylib3.o
     -Wl,-rpath -Wl,/opt/ELDK/ppc_8xx/lib -Wl,-rpath \
     -Wl,/opt/ELDK/ppc_8xx/lib /opt/ELDK/ppc_8xx/lib/libssh2.so \
     -L/opt/ELDK/ppc_8xx/lib -lz /opt/ELDK/ppc_8xx/lib/libgcrypt.so \
     /opt/ELDK/ppc_8xx/lib/libgpg-error.so -lpthread  -O2 \
     -Wl,-soname -Wl,mylib.so.0 -o .libs/mylib.so.0.0.0

2) В том же проекте есть несколько программ, которые ссылаются на «mylib». Однако, когда я пытаюсь связать их, я получаю ошибки компоновщика о тех же предыдущих библиотеках:

/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
     warning: libssh2.so.1, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
     warning: libz.so.1, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
     warning: libgcrypt.so.11, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
     warning: libgpg-error.so.0, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
./../myLib/.libs/mylib.so: undefined reference to `libssh2_channel_process_startup'
./../myLib/.libs/mylib.so: undefined reference to `libssh2_scp_send_ex'

В "mylib" configure.ac Я явно ищу библиотеки:

AC_SEARCH_LIBS(gpg_err_set_errno,[gpg-error])
AC_SEARCH_LIBS(gcry_check_version,[gcrypt])
AC_SEARCH_LIBS(deflate,[z])
AC_SEARCH_LIBS(libssh2_init,[ssh2])

Должен ли я также явно включать все эти библиотеки в каждый проект, использующий mylib? Разве это не должно быть решено, когда я впервые связываю их в «mylib»?

Есть ли лучший способ сделать это?

Спасибо.

P.S .: Я не очень умен в autoconf вопрос, извините.

ПРИМЕЧАНИЕ. Я выполняю кросс-компиляцию для PowerPC с использованием (еще старой) ELDK 3.1.

Ответы [ 2 ]

1 голос
/ 24 июля 2014

ПРИМЕЧАНИЕ: Поскольку я получил ответ 2 года спустя, и это не то, что решило мою проблему, я думаю, что лучше поделиться со всеми, что я сделал.


ОТВЕТ:

Лучшим способом автоматического включения зависимостей компоновщика в проект на основе autoconf было добавление информации pkg-config в мою библиотеку.

Меняется на configure.ac:

export PKG_CONFIG_PATH=../MyLibPath:${PKG_CONFIG_PATH}
PKG_CHECK_MODULES([DEPS], [libssh2 >= 1.3.0])

# Output configuration files.
AC_CONFIG_FILES([Makefile libMyLib-1.0.pc libMyLib-1.0-uninstalled.pc])

Второй выходной файл libMyLib-1.0-uninstalled.pc позволяет мне продолжить разработку проекта с удаленной версией MyLib.

Меняется на Makefile.am:

libMyLib_la_CPPFLAGS  = $(DEPS_CPPFLAGS)
libMyLib_la_CFLAGS    = $(DEPS_CFLAGS)
libMyLib_la_CXXFLAGS  = $(DEPS_CXXFLAGS)
libMyLib_la_LIBADD    = $(DEPS_LIBS)

pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libMyLib-1.0.pc

Добавить в проект libMyLib-1.0.pc:

prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@

Name: MyLib
Description: My library.
Requires: libssh2
Requires.private:
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lMyLib -lstdc++ -lm -lslog -lpthread
Libs.private:
Cflags: -I${includedir}/libMyLib-1.0

и libMyLib-1.0-uninstalled.pc:

prefix=@abs_builddir@
exec_prefix=@exec_prefix@
libdir=${prefix}/.libs
includedir=${prefix}

Name: MyLib
Description: My library.
Requires: libssh2
Requires.private:
Version: @PACKAGE_VERSION@
Libs: -Wl,-rpath-link,${libdir} -L${libdir} -lMyLib -lstdc++ -lm -lslog -lpthread
Libs.private:
Cflags: -I${includedir}/

В каждом зависимом проекте:

configure.ac

export PKG_CONFIG_PATH=../MyLibPath:${PKG_CONFIG_PATH}
PKG_CHECK_MODULES([MYLIB], [libMyLib-1.0 >= 1.0.0])

Makefile.am

dependent_CPPFLAGS  = $(MYLIB_CPPFLAGS)
dependent_CFLAGS    = $(MYLIB_CFLAGS)
dependent_CXXFLAGS  = $(MYLIB_CXXFLAGS)
dependent_LIBADD    = $(MYLIB_LIBS)
0 голосов
/ 23 июля 2014

Труднее точно сказать, что вы делаете, не зная, что у вас в Makefile.am или configure.ac, но, поскольку я вижу, что вы используете -Wl,-rpath, я предполагаю, что вы передаете его как LDFLAGS извне при звонке ./configure.

В результате libtool обычно не будет хранить значения -rpath, но будет -L; поэтому я обычно советую пропустить и -L, и -rpath, чтобы в файлах .la был указан путь, по которому можно найти библиотеки для ссылки на него.

Хотя вам не нужно передавать его в каждый двоичный файл, libtool сделает это и позволит редактору ссылок разрешить его правильно.

...