1) Mam projekt zawierający bibliotekę współdzieloną, która łączy się z niektórymi bibliotekami zagranicznymi (mianowicie gcrypt, gpg-error, z i ssh2). Nazwijmy to "mylib". Ta biblioteka buduje się doskonale i widzę, że libtool łączy poprawnie zależności.

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) Ten sam projekt ma kilka programów, które łączą się z „mylib”. Kiedy jednak próbuję je połączyć, otrzymuję błędy linkera dotyczące tych samych poprzednich bibliotek:

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

W "mylib" configure.ac jawnie szukam bibliotek:

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])

Czy muszę również jawnie uwzględnić wszystkie te biblioteki w każdym projekcie za pomocą „mylib”? Czy nie powinno to być już rozwiązane, gdy po raz pierwszy połączę je w „mylib”?

Czy jest lepszy sposób, aby to zrobić?

Dzięki.

PS: Nie jestem zbyt sprytny w sprawach autoconf, przepraszam.

UWAGA: Kompiluję krzyżowo dla PowerPC używając (jeszcze starego) ELDK 3.1.

1
j4x 24 luty 2012, 20:37

2 odpowiedzi

Najlepsza odpowiedź

UWAGA: Ponieważ otrzymałem odpowiedź 2 lata później i nie to rozwiązało mój problem, myślę, że lepiej podzielić się ze wszystkimi tym, co zrobiłem.


odpowiedź:

Lepszym sposobem, w jaki odkryłem automatyczne dołączanie zależności linkera w projekcie opartym na autoconf, było dodanie informacji pkg-config do mojej biblioteki.

Zmiany w 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])

Drugi plik wyjściowy libMyLib-1.0-uninstalled.pc ma pozwolić mi na dalsze rozwijanie mojego projektu z odinstalowaną wersją MyLib.

Zmiany w 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

Dodaj do projektu 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

i 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}/

W każdym projekcie zależnym:

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)
1
j4x 24 lipiec 2014, 17:09

Trudniej jest dokładnie określić, co robisz, nie wiedząc, co jest w twoim Makefile.am lub configure.ac, ale ponieważ widzę, że używasz -Wl,-rpath, zakładam, że przekazujesz to jako LDFLAGS z zewnątrz, gdy zadzwonisz ./configure.

Dzieje się tak, że libtool zwykle nie przechowuje wartości -rpath, ale przechowuje -L; więc moją zwykłą sugestią jest przekazanie zarówno -L, jak i -rpath, aby pliki .la zawierały ścieżkę, w której można znaleźć biblioteki do linkowania do nich.

Chociaż nie musisz przekazywać go do każdego pliku binarnego, libtool to zrobi, a następnie pozwoli edytorowi linków rozwiązać go poprawnie.

0
Diego Elio Pettenò 23 lipiec 2014, 13:18