最近学习sylar项目,编译项目时遇到链接库不匹配的问题,记录下自己解决问题过程,虽然过程很艰难,但还是解决了,以下内容供大家参考!
undefined reference to ``问题分析
-
项目编译报错
/usr/bin/ld: ../lib/libsylar.so: undefined reference to `ZOO_READONLY_STATE' /usr/bin/ld: ../lib/libsylar.so: undefined reference to `zookeeper_init2' /usr/bin/ld: ../lib/libsylar.so: undefined reference to `zoo_set_servers' /usr/bin/ld: ../lib/libsylar.so: undefined reference to `ZOO_NOTCONNECTED_STATE' /usr/bin/ld: ../lib/libsylar.so: undefined reference to `zoo_get_current_server' /usr/bin/ld: ../lib/libsylar.so: undefined reference to `ZOO_CONTAINER'
-
应该是链接到的库文件中不含这些字符,因为之前是
sudo apt-get install libzookeeper-dev
安装的,版本较久(3.4.13),我也看了它的头文件源码,确实没有这些定义变量和函数;(注意这里的我看的是zookeeper.h
头文件,而libzookeeper_mt.so
文件是安装编译时产生的,因此两个文件内容是一致的;下面讲下如何通过二进制文件libzookeeper_mt.so
来查看是否包含某种字符) -
查看验证
libzookeeper_mt.so
链接文件是否包含对应的字符find / -name libzookeeper_mt.so
在/usr/lib/libzookeeper_mt.so
定位找到了链接文件;nm -D libzookeeper_mt.so | grep ZOO_READONLY_STATE
查看这个二进制文件中的可显示字符是否有报错的字符,发现并没有,可以确定当前系统安装库的zookeeper版本的确没有对应变量和函数定义,那么就需要安装新的版本库;
编译安装zookeeper
我之前通过
apt
安装的,并且查看了下里面源库中没有更新的版本,因此只能下载库安装包,手动编译安装;
zookeeper下载地址 https://dlcdn.apache.org/zookeeper/
-
下载安装包后,可以查看
README_packaging.md
,里面详细讲解了如何构建和安装这个库,并且指出最终生成的链接文件路径;具体操作如下:- 依赖软件包安装命令
RHEL系统:
yum install cppunit yum install python-setuptools yum install openssl openssl-devel yum install cyrus-sasl-md5 cyrus-sasl-gssapi cyrus-sasl-devel
Ubuntu系统(适用于 16.04+):
apt-get install libcppunit-dev apt-get install python-setuptools python2.7-dev apt-get install openssl libssl-dev apt-get install libsasl2-modules-gssapi-mit libsasl2-modules libsasl2-dev
- 使用 Maven (没有指令的话需要安装)构建包:以下命令将清理所有内容并构建 tarball 包,同时跳过测试:
mvn clean install -DskipTests
- 构建 C 客户端,需要激活
full-build
配置文件:
mvn clean -Pfull-build mvn install -Pfull-build -DskipTests
- 编译后文件位置
- 用户可执行文件在 `zookeeper-client/zookeeper-client-c/target/c/bin`。 - 原生库在 `zookeeper-client/zookeeper-client-c/target/c/lib`。 // 我们所需的链接文件路径 - 原生库头文件在 `zookeeper-client/zookeeper-client-c/target/c/include/zookeeper`。
- 依赖软件包安装命令
-
如果构建安装顺利的话,就可以看到成功显示;
-
下述就是需要的链接文件,然后将对应的文件复制到
/usr/lib/ 或者 /usr/local/lib/
下,保证系统编译器可以找到;
-
构建时如果报错,例如需要添加JAVA_HOME环境变量,在
~/.bashrc
文件中添加,自己安装JAVA的jdk路径即可;
具体操作见:https://blog.csdn.net/weixin_50570038/article/details/143256298
最后检查下是否成功
此时发现可以找到ZOO_READONLY_STATE字符变量,完结!!
通过以上操作,可以解决编译项目过程中,遇到链接文件可能由于版本不支持导致无法成功编译的问题;
反正遇到问题不要怕,一步步分析、解决,这个过程也可以深入理解linux系统下的编译过程(虽然我花了两天才解决这个问题)