这两天需要把项目做成静态链接版本,便于在各公司的各种linux平台上运行。

我想这还不简单,链接参数加一个-static不就行了,但接下来解决一系列问题的时间远远超出我的意料

开发环境:

CentOS release 5.8 (Final)

gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52)

问题是由于静态链接mysql库引起的,我链接mysql库的参数是这样写的:

LIB_MYSQL     = $(shell mysql_config --libs)

发现静态链接悲剧了,好几百个链接错误,都是undefined,需要krb5库。链接加上krb5库:

LIB_KBR5     = $(shell krb5-config --libs)

最终部分链接参数是这样的:$(LIB_MYSQL) $(LIB_KBR5) $(LIB_THREAD) -static

结果链接器还是报错:

/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_get_principal':
(.text+0xfaa): undefined reference to `keyctl_read_alloc'
/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_getkeycount':
(.text+0x1129): undefined reference to `keyctl_read'
/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_clearcache':
(.text+0x1194): undefined reference to `keyctl_clear'
/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_clearcache':
(.text+0x11c1): undefined reference to `keyctl_clear'
/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_resolve':
(.text+0x1692): undefined reference to `request_key'
/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_resolve':
(.text+0x16bb): undefined reference to `keyctl_read'
/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_resolve':
(.text+0x170c): undefined reference to `keyctl_search'
/usr/lib64/libkrb5.a(cc_keyring.o): In function `krb5_krcc_resolve':
(.text+0x1733): undefined reference to `add_key'

......

接下来就是排查是不是还缺什么库啊,缺什么链接时就加什么,结果都没能把undefined完全消灭。很郁闷,就静态链接mysql库,这都搞不定?

折腾了很久,还是把问题描述给一个朋友听,经他提醒,才想到是不是我用yum自动安装mysql的问题,要不自己下载mysql源码包,手动编译安装试试?下载了mysql-5.5.29.tar.gz,经过tar -xvf,cmake,make,make install,并且把链接mysql的链接参数手动指定了一下:
LIB_MYSQL     = /usr/local/mysql/lib/libmysqlclient.a

哈哈,的确不需要链接krb5的库了,但是有几个新的undefined,但是还好,只有几个,而且清晰:

/usr/local/mysql/lib/libmysqlclient.a(client_plugin.c.o): In function `add_plugin':
/home/rsm/mysql-5.5.29/sql-common/client_plugin.c:178: undefined reference to `dlclose'
/usr/local/mysql/lib/libmysqlclient.a(client_plugin.c.o): In function `mysql_load_plugin_v':
/home/rsm/mysql-5.5.29/sql-common/client_plugin.c:354: undefined reference to `dlopen'
/home/rsm/mysql-5.5.29/sql-common/client_plugin.c:382: undefined reference to `dlsym'
/home/rsm/mysql-5.5.29/sql-common/client_plugin.c:374: undefined reference to `dlerror'
/home/rsm/mysql-5.5.29/sql-common/client_plugin.c:385: undefined reference to `dlclose'

于是,链接的库增加libdl.a(属于glibc里的),部分链接参数如下:

-lcrypt -L/usr/local/mysql/lib/ -lmysqlclient -ldl -lpthread -static

哦也,终于链接过了!虽然有几个让人讨厌的warning:

/usr/local/mysql/lib//libmysqlclient.a(client_plugin.c.o): In function `mysql_load_plugin_v':
/home/win/mysql-5.5.29/sql-common/client_plugin.c:354: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib//libmysqlclient.a(mf_pack.c.o): In function `expand_tilde':
/home/win/mysql-5.5.29/mysys/mf_pack.c:387: warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib//libmysqlclient.a(libmysql.c.o): In function `read_user_name':
/home/win/mysql-5.5.29/libmysql/libmysql.c:422: warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib//libmysqlclient.a(mf_pack.c.o): In function `expand_tilde':
/home/win/mysql-5.5.29/mysys/mf_pack.c:389: warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/mysql/lib//libmysqlclient.a(client.c.o): In function `mysql_real_connect':
/home/win/mysql-5.5.29/sql-common/client.c:3247: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../lib64/libpthread.a(libpthread.o): In function `sem_open':
(.text+0x764d): warning: the use of `mktemp' is dangerous, better use `mkstemp'
/usr/local/mysql/lib//libmysqlclient.a(libmysql.c.o): In function `mysql_server_init':
/home/win/mysql-5.5.29/libmysql/libmysql.c:153: warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

于是很激动的启进程,刚起来,就宕掉了!!!!用GDB起来,发现是宕在调用libdl的库里。

其实上面的7个warning中,后面6个我认识的:在以前的另一个项目中(环境是ubuntu server),也是静态链接,一直都有后面这6个warning,但是这几个函数没有用到,所以进程没有问题,当时项目进度又异常的紧,大家就一直没有花心思去研究消掉这几个warning。现在新增加的第一个warning,其中dlopen会调用到,会造成宕机,这下无法逃避,所以我接下来的精力就花在消除这几个warning上。

就是这么一个问题:Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking,这是一个很常见的问题:

static linking issue with glibc

但是我各种关键字组合google搜索,发现问这个问题的人不少,讨论也很热烈,但是都没有人给出解决问题的方案,下面两个连接是比较明确的:

http://bytes.com/topic/c/answers/877929-lnk-error-using-dlopen-statically-linked-apps-requires-runtime-shared-lib

https://bugzilla.redhat.com/show_bug.cgi?id=111298

http://www.qtcentre.org/threads/32521-Problems-with-static-linking-gt-segmentation-fault

其中有个老外说了下面一段:

Jakub Jelinek 2003-12-01 17:49:41 EST

If a RHL9 built statically linked binary using NSS works on older  glibcs, then you are just lucky, nothing else.  It certainly will not  work on all older glibcs, only on some and only under some circumstances.  Statically linked programs which are not self-contained and depend  on the installed glibc (be it because of using NSS or iconv (which  both dlopen glibc internally), using dlopen directly or even using  locale support) are really the least portable thing you can build.    Dynamically linking is uncomparably more portable.  You can link some libraries statically using -Bstatic -lfoo -lbar -Bdynamic,  yet link against the crucial system libraries dynamically.    The warnings were added so that everyone is aware of the problems  with -static.  For statically linked binaries using NSS/iconv/dlopen  the dynamic linker needs to be compiled into the statically linked  program, yet the shared libraries it loads come from a different  glibc if the statically linked binary is moved onto a different system.  This means the glibc private interface between the dynamic linker  and libc.so/libpthread.so is exposed, but this interface is constantly  changing (and has been changing for years in the past as well).    So, the only supported way of using NSS/iconv/dlopen in statically  linked programs is if they are compiled/linked against the same glibc  as they are run with.

搜索可以打开这个页面:

http://www.google.com.hk/search?hl=en&source=hp&q=Using+'gethostbyname'+in+statically+linked+applications+requires+at+runtime+the+shared+libraries+from+the+glibc+version+used+for+linking&aq=f&oq=&aqi=

不过都没能解决问题,warning依然存在。朋友还提醒,是不是系统版本装的有问题?或者开发环境装的有问题?好吧,我已经没有更好的方法了,还让IT的同事重新找电脑装了新环境CentOS6.3 DVD版,折腾了很久,编译,链接,结果还是那7个warning,它们就死死的杵在那里!

最终,这个问题都没能解决。但是项目得继续,所以最终采用了一个折中方案:

mysql和另一些自有库静态链接,glibc,libstdc++等一些常见的基础库动态链接。

-Wl,-dn 其它自己的静态库 -L/usr/local/mysql/lib/ -lmysqlclient -Wl,-dy -lpthread -ldl -lcrypt

据说,这才是标准做法~~ 因为网上有人反问:为什么要静态链接glibc库?

当然,也可以直接在编译阶段将静态库编进项目里,例如:

g++ main.cpp libmysqlclient.a

linux 静态链接 mysql glibc 库的悲催过程相关推荐

  1. linux 静态链接 mysql glibc 库的悲催过程 - mango的日志 - 网易博客

    linux 静态链接 mysql glibc 库的悲催过程 - mango的日志 - 网易博客 linux 静态链接 mysql glibc 库的悲催过程 - mango的日志 - 网易博客 linu ...

  2. 【转载】linux静态链接库与动态链接库的区别及动态库的创建

    这篇文章对于动态库的概念及使用介绍的很不错,故收藏了. 一.引言 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数 ...

  3. libcurl linux 静态链接库_GCC 程序编译的静态链接和动态链接

    转自:Mr_Bluyee 在链接阶段中,所有对应于源文件的 .o 文件."-l" 选项指定的库文件.无法识别的文件名(包括指定的.o目标文件和.a库文件)按命令行中的顺序传递给链接 ...

  4. libcurl linux 静态链接库_Linux ubuntu OpenSSL + curl 静态库编译及使用

    下载源码 源码编译 解压之后,进入源码目录openssl-1.1.0f,执行如下命令.因为只需要编译静态库,也没有特殊要求,所以使用的编译选项配置很简单: ./config -fPIC no-shar ...

  5. Linux 静态链接库与动态链接库之一:静态链接库生成及使用

    (1)引言       通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文 ...

  6. libcurl linux 静态链接库_Linux学习:Makefile 模板(动态库、静态库、可执行程序)...

    1.编译动态库 ############################################################# # Makefile for shared library. ...

  7. linux静态链接库添加,c-静态链接库时,出现链接器错误:找不到-...

    使用g前端执行链接时,例如: g++ -o prog prog.o -Wl,-Bstatic -lcurl g调用链接器,将其传递给您的链接选项,并且也进行静默 向链接器命令行添加了大量样板选项,这些 ...

  8. 怎么在linux下用mysql建库_在MySQL/MariaDB中创建数据库、数据库用户和授予特权(针对Linux平台)...

    在本文中,将学习MySQL/MariaDB数据库创建.数据库用户创建以及如何向用户授予权限,方法针对Linux平台.安装数据库请参考为CentOS 8操作系统安装MySQL的方法,以安装MySQL 8 ...

  9. linux同时链接多个库,通过Shell脚本同时监控多个数据库负载

    在平时的工作中,需要管理的数据库还是很多的,因为远程和权限的关系,访问不了一些图形工具,有时候做检查的时候感觉都是一个串行的过程,这样检查针对性就不够强了,比如我们不知道在检查的这个时间范围内,数据库 ...

最新文章

  1. LSPCI具体解释分析
  2. onethink封装arclist调用文章列表!
  3. 云炬Android开发笔记 3-2字体图标库集成与封装
  4. write up::web 实战2-注入 --sqlmap注入版
  5. 信息学奥赛一本通(1111:不高兴的津津)
  6. Github | 如何用Python测试GPU与CPU计算性能
  7. 深度学习(七十二)tensorflow 集群训练
  8. 微软高性能计算服务器pdf,微软高性能计算HPCserver2008技术概览.pdf
  9. Linux中httpd353错误,linux - 由于控制进程退出并显示错误代码,因此httpd.service的作业失败 - 堆栈内存溢出...
  10. 如何打开剪贴板查看器?
  11. 印刷纸张尺寸,纸张种类规格
  12. 如何修复win7蓝牙服务器,win7系统查看蓝牙的修复办法
  13. [补集转化 有序化去重] Ural 1212 Battleship
  14. PredRNN++:网络结构和代码解读
  15. 从动物纪录片中所学所得
  16. i9 13900ks和13900k区别 i913900ks和i913900k对比
  17. Interactive natural language question answering over knowledge graphs论文导读
  18. 在计算机海洋里摸爬滚打搜集的一些资源
  19. 解决“VirtualBox VERR_NEM_INIT_FAILED“问题
  20. 计算机图形学实验一(二维图形绘制)

热门文章

  1. MA8621设计读卡功能的USB HUB集线器方案
  2. 截图像素大小和实际图片大小不同
  3. R `summarise()` ungrouping output (override with `.groups` argument)
  4. Netty的启动执行过程分析(一)
  5. mac os 安装mysql经验
  6. 给C语言添加花指令,抵御反汇编
  7. 和氟西汀类似的备注_备注氟西汀是什么意思和梗 让我做你的氟西汀出处意义...
  8. filebeat7.7.0相关详细配置预览- processors - add_id
  9. 4+1 视图模型与软件建模UML
  10. 高仙主导丨中国电器工业协会发布首个商用清洁服务机器人团体标准