LIBSSH2和dso_dlfcn.c:...对'dlopen'的未定义引用

时间:2016-04-15 14:44:01

标签: linker openssl static-linking libgit2 libssh2

我正在尝试使用静态git2golibgit2openssl来汇编libssh2。我的最终目标是能够编译可以部署的go二进制文件,而无需安装这些库。我在SO上找到了类似的question,我用它来创建以下构建库的脚本

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

LIBSSH2:

#!/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的{​​{1}}分支next中的脚本,以确保libgit2指向静态PKG_CONFIG_PATH }和openssl

LIBGIT2:

libssh2

此设置最终会创建一个本地--- 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答案都无济于事。任何帮助将不胜感激

2 个答案:

答案 0 :(得分:0)

由于我不熟悉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

这成功编译。

答案 1 :(得分:0)

我发现将target_link_libraries(libssh2 ${CMAKE_DL_LIBS})添加到src/CMakeLists.txt(正如here所述)解决了问题中提到的问题。请注意,我使用的是libssh2-1.8.0和最新的OpenSSL(5de683d),但我认为这与OpenSSL_1_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的最新版本的未定义引用。