文章目录
  1. 1. 问题描述
  2. 2. 发生的场景及原因
  3. 3. 解决方案
  4. 4. 案例剖析(Alibaba/Tair)
    1. 4.1. 编译期错误一
      1. 4.1.1. 产生原因
      2. 4.1.2. 解决方案
    2. 4.2. 编译期错误二
      1. 4.2.1. 产生原因
      2. 4.2.2. 解决方案
    3. 4.3. 编译期错误三
      1. 4.3.1. 产生原因
      2. 4.3.2. 解决方案
    4. 4.4. 其它
  5. 5. 参考资料

问题描述

由于Linux Kernel或编译器版本升级后,经常对原有工程项目编译期遇到如下问题:

1
error adding symbols: DSO missing from command line

发生的场景及原因

  • 我们有一个shared libA中,定义了函数foo()

  • 另一个静态库libB显示地链接了libA

  • 一个可执行文件bin_c显示地链接了libB

  • 那么问题来了,如果bin_c中调用了函数foo(),那么编译能不能通过?

    • 在binutils<2.22时,ld正常完成了,bin_c对于foo的调用经由libB,传递到了libA,链接成功。
    • 但是当binutils>=2.22时,编译出错了,ld会报上面的错,告诉你foo这个symbol解析不到,这时,我们需要编译bin_c时,显示地链接libA才可以通过。
    • binutils2.22开始,其中的ld开始把–no-copy-dt-needed-entries默认打开,这样一来,ld不会再自动递归地解析链接的lib,而需要由用户来一一指定。

解决方案

  • 一个ld的选项–allow-shlib-undefined,作用是允许在动态库中存在未解析到的函数symbol,至于理由可以自行查看man.
  • 编译期修改Makefile LINK选项,手动加入全部依赖.(推荐方法)

案例剖析(Alibaba/Tair)

  • 以Tair为例,其Github地址为:Alibaba/Tair
  • 编译环境:CentOS 5.4 GCC 4.9.3 BOOST-1.57.0

编译期错误一

1
/lib64/libcrypto.so.6: error adding symbols: DSO missing from command line

产生原因

  • 编译器使用的是GCC 4.9.3, 高于CentOS 5.4系统标配,其相关的ld等版本也高于2.24, 故在编译期时不会自动引入递归依赖,因此报错.
  • 如果采用GCC 4.1.2, 则不会报错.
  • Tair所需要的snappy版本其编译依赖高于系统自带,需要手动安装ld相关. 见参考文献.

解决方案

  • 手动加入-lcrypto编译选项.

编译期错误二

1
2
httpclient.hpp:122:36: error: static data member ‘System::Net::HttpWebRequest::<anonymous struct>::POST’ in unnamed class [-fpermissive]
const static std::string POST;

产生原因

1
2
3
4
5
6
7
8
9
class A
{
public:
typedef struct {
const static std::string POST;
const static std::string GET;
const static std::string DELETE;
} Method;
};
  • GCC 4.9.3不再支持该定义语法(即在类内定义匿名类,进而定义静态常量成员).

解决方案

  • 升级代码,使之兼容C++ 11标准.

编译期错误三

1
2
tair_client_api_impl.cpp:4079:15: error: variable 'get_statistics_success' set but not used [-Werror=unused-but-set-variable]
bool get_statistics_success = true;

产生原因

  • GCC编译选项配置导致.

解决方案

  • 找到对应目录中的Makefile文件,找到 -Werror 字段,去掉-Werror,重新编译,则问题解决!
  • 根据提示修改源代码,去掉无用变量,减少代码冗余和在编译优化过程中可能导致的致命错误!(推荐)

其它

  • gflags增加-fPIC: SET(CMAKE_CXX_FLAGS “-fPIC”) [CMakeLists.txt]
  • glog增加-fPIC: CXXFLAGS = -fPIC [Makefile]

参考资料

文章目录
  1. 1. 问题描述
  2. 2. 发生的场景及原因
  3. 3. 解决方案
  4. 4. 案例剖析(Alibaba/Tair)
    1. 4.1. 编译期错误一
      1. 4.1.1. 产生原因
      2. 4.1.2. 解决方案
    2. 4.2. 编译期错误二
      1. 4.2.1. 产生原因
      2. 4.2.2. 解决方案
    3. 4.3. 编译期错误三
      1. 4.3.1. 产生原因
      2. 4.3.2. 解决方案
    4. 4.4. 其它
  5. 5. 参考资料