LIBSSH2 и dso_dlfcn.c: неопределенная ссылка на `dlopen'

Я пытаюсь скомпилировать git2go, используя статические libgit2, openssl и libssh2. Моя конечная цель — иметь возможность скомпилировать двоичный файл go, который можно будет развернуть без необходимости установки этих библиотек. Я нашел аналогичный вопрос на SO, который я использовал для создайте следующие сценарии, которые создают библиотеки

OPENSSL:

#!/bin/sh

set -ex
INSTALL_PATH="$PWD/install"
SUBMODULE_PATH="$PWD/submodules/openssl"

cd $SUBMODULE_PATH &&
mkdir -p $INSTALL_PATH/lib &&
mkdir -p build &&

# Switch to a stable version
git checkout OpenSSL_1_0_2-stable &&
./config threads no-shared --prefix=$INSTALL_PATH -fPIC -DOPENSSL_PIC &&
make depend &&
make &&
make install

ЛИБСШ2:

#!/bin/sh

set -ex

INSTALL_PATH="$PWD/install"
SUBMODULE_PATH="$PWD/submodules/libssh2"

# without this, the system's openssl shared object gets linked in
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$INSTALL_PATH/lib/pkgconfig:$INSTALL_PATH/lib64/pkgconfig"

cd $SUBMODULE_PATH &&
mkdir -p $INSTALL_PATH/lib &&
mkdir build
cd build &&
cmake -DTHREADSAFE=ON \
      -DBUILD_CLAR=OFF \
      -DBUILD_SHARED_LIBS=OFF \
      -DCMAKE_C_FLAGS=-fPIC \
      -DCMAKE_BUILD_TYPE="RelWithDebInfo" \
      -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH \
      .. &&

cmake --build .
make install

Я применяю следующий патч к скрипту в git2go ветке next, который создает libgit2, чтобы убедиться, что PKG_CONFIG_PATH указывает на статические библиотеки openssl и libssh2.

ЛИБГИТ2:

--- build-libgit2-static.sh.orig    2016-04-14 22:49:53.000000000 -0700
+++ build-libgit2-static.sh 2016-04-14 22:52:04.000000000 -0700
@@ -2,10 +2,12 @@

 set -ex

-VENDORED_PATH=vendor/libgit2
+INSTALL_PATH="$PWD/install"
+VENDORED_PATH="$PWD/submodules/git2go/vendor/libgit2"
+export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$INSTALL_PATH/lib/pkgconfig:$INSTALL_PATH/lib64/pkgconfig"

 cd $VENDORED_PATH &&
-mkdir -p install/lib &&
+mkdir -p $INSTALL_PATH/lib &&
 mkdir -p build &&
 cd build &&
 cmake -DTHREADSAFE=ON \
@@ -13,7 +15,8 @@
       -DBUILD_SHARED_LIBS=OFF \
       -DCMAKE_C_FLAGS=-fPIC \
       -DCMAKE_BUILD_TYPE="RelWithDebInfo" \
-      -DCMAKE_INSTALL_PREFIX=../install \
+      -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH \
       .. &&

 cmake --build .
+make install

Эта установка в конечном итоге создает локальный каталог install, в котором установлены все библиотеки. Я компилирую openssl, используя приведенный выше скрипт. Затем получите следующий вывод при компиляции libssh2:

...
Found OpenSSL: (path to project)/install/lib/libssl.a;(path to project)/install/lib/libcrypto.a (found version "1.0.2h-dev")
...
Linking C static library libssh2.a
gmake[3]: Leaving directory `(path to project)/submodules/libssh2/build'
[ 46%] Built target libssh2
gmake[3]: Entering directory `(path to project)/submodules/libssh2/build'
Scanning dependencies of target example-direct_tcpip
gmake[3]: Leaving directory `(path to project)/submodules/libssh2/build'
gmake[3]: Entering directory `(path to project)/submodules/libssh2/build'
[ 48%] Building C object example/CMakeFiles/example-direct_tcpip.dir/direct_tcpip.c.o
Linking C executable example-direct_tcpip
(path to project)/install/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
dso_dlfcn.c:(.text+0x11): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x24): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x2f): undefined reference to `dlclose'
(path to project)/install/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
dso_dlfcn.c:(.text+0x354): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x412): undefined reference to `dlerror'
(path to project)/install/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
dso_dlfcn.c:(.text+0x484): undefined reference to `dlsym'
dso_dlfcn.c:(.text+0x542): undefined reference to `dlerror'
(path to project)/install/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
dso_dlfcn.c:(.text+0x5a9): undefined reference to `dlopen'
dso_dlfcn.c:(.text+0x60d): undefined reference to `dlclose'
dso_dlfcn.c:(.text+0x645): undefined reference to `dlerror'
(path to project)/install/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
dso_dlfcn.c:(.text+0x6d1): undefined reference to `dladdr'
dso_dlfcn.c:(.text+0x731): undefined reference to `dlerror'
(path to project)/install/lib/libcrypto.a(dso_dlfcn.o): In function `dlfcn_unload':
dso_dlfcn.c:(.text+0x792): undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
gmake[3]: Leaving directory `(path to project)/submodules/libssh2/build'
gmake[2]: Leaving directory `(path to project)/submodules/libssh2/build'
gmake[1]: Leaving directory `(path to project)(path to project)/submodules/libssh2/build'
gmake[3]: *** [example/example-direct_tcpip] Error 1
gmake[2]: *** [example/CMakeFiles/example-direct_tcpip.dir/all] Error 2
gmake[1]: *** [all] Error 2
make: *** [build-libssh2] Error 2

Вы можете видеть, что используется статический openssl. Очевидно, что libdl не связывается с libcrypto. Вывод при компиляции openssl имеет EX_LIBS=-ldl. Должна ли это включать библиотеку? Я пытался использовать LDLIBS=-ldl в сценарии установки openssl, но все равно та же ошибка. Я пробовал почти каждый ответ SO для поискового запроса libcrypto undefined reference to 'dlopen' безрезультатно. Любая помощь приветствуется


person arynhard    schedule 15.04.2016    source источник
comment
Также см. Не удается найти ошибку библиотеки libcrypto и комментарий Вам нужно добавить -ldl при выполнении последней ссылки. Кроме того, я пытался использовать LDLIBS=-ldl при установке openssl... - проблемы возникают с libssh, а не с libcrypto.   -  person jww    schedule 16.04.2016
comment
@jww, если libssh ищет ссылку, то почему ошибка говорит libcrypto.a ... неопределенная ссылка ...? Немного запутанно   -  person arynhard    schedule 16.04.2016
comment
libcrypto.a имеет зависимость. Вы можете связать свою окончательную программу или libssh2 — в обоих случаях вам нужно будет добавить -ldl, потому что это зависимость. OpenSSL компилируется и связывается с ним, так что это не является неудовлетворенной зависимостью при сборке OpenSSL. Вы можете запретить использование OpenSSL функций управления файлами, настроив no-dso.   -  person jww    schedule 16.04.2016


Ответы (2)


Поскольку я не знаком с pig-config, я переключился на Autoconf:

#!/bin/sh

set -ex

INSTALL_PATH="$PWD/install"
SUBMODULE_PATH="$PWD/submodules/libssh2"

mkdir -p $INSTALL_PATH/lib &&
cd $SUBMODULE_PATH &&
./buildconf
./configure --prefix=$INSTALL_PATH --libdir=$INSTALL_PATH/lib64 --with-openssl CFLAGS="-fPIC" LDFLAGS="-m64 -L$INSTALL_PATH/lib -L$INSTALL_PATH/lib64" LIBS=-ldl
make
make install

Это успешно компилируется.

person arynhard    schedule 16.04.2016

Я обнаружил, что добавление target_link_libraries(libssh2 ${CMAKE_DL_LIBS}) к src/CMakeLists.txt (как объяснено здесь) решает проблему, упомянутую в вопросе. . Обратите внимание, что я использую libssh2-1.8.0 и последнюю версию OpenSSL (5de683d), но я думаю, что та же история с OpenSSLtarget_link_libraries(libssh2 ${CMAKE_DL_LIBS})0_2-stable.

Итак, работающий код сборки LIBSSH2:

# inside libssh2 root
printf '\ntarget_link_libraries(libssh2 ${CMAKE_DL_LIBS})' >> src/CMakeLists.txt
mkdir build && cd build
cmake -DTHREADSAFE=ON \
      -DBUILD_CLAR=OFF \
      -DBUILD_SHARED_LIBS=OFF \
      -DCMAKE_C_FLAGS=-fPIC \
      -DCMAKE_BUILD_TYPE="RelWithDebInfo" \
      -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH \
      .. &&
cmake --build .
make install

Примечание. Мне также пришлось добавить target_link_libraries(libssh2 pthread), потому что я получал неопределенные ссылки на pthread в последних версиях.

person Calin    schedule 05.03.2018