【问题标题】:How to compile to avoid shared library errors?如何编译避免共享库错误?
【发布时间】:2011-11-23 15:25:23
【问题描述】:

我需要使用 MySQL C API 开发程序。我将在我的 CentOS 虚拟机上开发它并在 RedHat 服务器上运行它。我编译了某种 Hello World 程序并将其传输到服务器。但我收到有关共享库的错误。

$ ./test1
./test1: error while loading shared libraries: libssl.so.10: cannot open shared object file: No such file or directory

我看到这个库存在,但名称略有不同:

$ ls -l /usr/lib/libssl*
-rw-r--r-- 1 root root 458752 Aug 13 17:27 /usr/lib/libssl.a
lrwxrwxrwx 1 root root     26 Sep 14 01:26 /usr/lib/libssl.so -> ../../lib/libssl.so.0.9.8er
-rwxr-xr-x 1 root root 217560 Nov  9 12:22 /usr/lib/libssl3.so

由于我不是服务器上的 root,我不能简单地创建符号链接。我会将我的程序分发给许多没有 root 权限和系统管理技能的人。有没有一种安全的方法来编译我的程序以避免此类错误?

这是我的简单程序:

#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv)
{
  printf("MySQL client version: %s\n", mysql_get_client_info());
}

而且,这就是我编译它的方式:

gcc version.c -o version  `mysql_config --cflags --libs`

ldd ./test1 的输出:

linux-gate.so.1 =>  (0x00685000)
libmysqlclient.so.16 => /usr/lib/mysql/libmysqlclient.so.16 (0x00a8c000)
libz.so.1 => /lib/libz.so.1 (0x00110000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x00240000)
libnsl.so.1 => /lib/libnsl.so.1 (0x002b7000)
libm.so.6 => /lib/libm.so.6 (0x00f5a000)
libssl.so.10 => /usr/lib/libssl.so.10 (0x00e0c000)
libcrypto.so.10 => /usr/lib/libcrypto.so.10 (0x002d1000)
libc.so.6 => /lib/libc.so.6 (0x004d3000)
libfreebl3.so => /lib/libfreebl3.so (0x00686000)
/lib/ld-linux.so.2 (0x00977000)
libgssapi_krb5.so.2 => /lib/libgssapi_krb5.so.2 (0x006ea000)
libkrb5.so.3 => /lib/libkrb5.so.3 (0x00123000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x00804000)
libk5crypto.so.3 => /lib/libk5crypto.so.3 (0x001f4000)
libresolv.so.2 => /lib/libresolv.so.2 (0x0021b000)
libdl.so.2 => /lib/libdl.so.2 (0x00dbf000)
libkrb5support.so.0 => /lib/libkrb5support.so.0 (0x00234000)
libkeyutils.so.1 => /lib/libkeyutils.so.1 (0x00f0b000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00e72000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00862000)

mysql_config --cflags --libs 的输出:

-I/usr/include/mysql  -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -fasynchronous-unwind-tables -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fno-strict-aliasing -fwrapv -fPIC   -DUNIV_LINUX
-rdynamic -L/usr/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -lssl -lcrypto

【问题讨论】:

  • 你的mysql_config --cflags --libs 说什么? ldd ./test1 说什么?
  • @unbeli:我将其添加到问题中以提高可读性。

标签: mysql linux gcc shared-libraries


【解决方案1】:

您的二进制文件是针对 openssl 版本 1.0.x 编译的,因此需要 openssl 主版本 1。目标机器的版本为 0.9.8,即主版本 0。不同的主版本被认为不兼容,因此出现错误。

【讨论】:

  • 不知道每台服务器安装的是哪个版本。有没有办法制作“一刀切”的二进制文件?静态链接等?
  • 静态链接可以工作。如果您不想要完全静态链接,您可以浏览 ldd 列表并选择目标机器上可能不存在和/或不同版本的库。
  • 与流行的看法相反,Linux 二进制文件的静态链接通常不起作用。任何使用getpwnam 的二进制文件在静态链接时都会发出警告,如果在安装了不同版本的 glibc 的系统上运行,则可能会崩溃。
  • @EmployedRussian 那么,人们如何分发他们的程序?
  • 我可以将我在程序中使用的一组库捆绑在一起发送吗?
【解决方案2】:

阅读ld.so 及其变量,例如LD_LIBRARY_PATHLD_PRELOAD——您可以在自己的~/lib/ 中安装libssl.so,然后让动态链接器找到它。

不用说,您最好通过包管理系统执行此操作。

【讨论】:

  • 对不起,我听不懂你的意思。你能再解释一下吗?
猜你喜欢
  • 2019-05-03
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多