让C/C++程序一次编译可以发布到多版本Linux之上

简介: 最近页游开放平台比较多, 每个平台要求的Linux版本各不相同, 这给开发人员部署服务器带来了很大的困难. 在本机Linux编译的程序,发布时即便将依赖的so附带到目标Linux环境,仍然会碰到依赖及版本问题,例如: [root@localhost bin]# ldd wkcenter .

最近页游开放平台比较多, 每个平台要求的Linux版本各不相同, 这给开发人员部署服务器带来了很大的困难. 在本机Linux编译的程序,发布时即便将依赖的so附带到目标Linux环境,仍然会碰到依赖及版本问题,例如:

[root@localhost bin]# ldd wkcenter 
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./wkcenter)
./wkcenter: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.9' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.7' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.8' not found (required by ./wkcenter)
./wkcenter: /lib/libc.so.6: version `GLIBC_2.11' not found (required by ./wkcenter)

        linux-gate.so.1 =>  (0xffffe000)
        liblog4cpp.so.4 => not found
        libprotobuf.so.7 => not found
        libboost_filesystem.so.1.48.0 => not found
        libboost_system.so.1.48.0 => not found
        libboost_thread.so.1.48.0 => not found
        libboost_program_options.so.1.48.0 => not found
        libunwind-x86.so.7 => not found
        libluabind.so.0.9.0 => not found
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x008ae000)
        libm.so.6 => /lib/libm.so.6 (0x0044b000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00476000)
        libc.so.6 => /lib/libc.so.6 (0x002c1000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x0041d000)
        librt.so.1 => /lib/librt.so.1 (0x00440000)
        /lib/ld-linux.so.2 (0x002a2000)

上面红字部分表示glibc及glibcxx库依赖不正确. 本人使用的Linux编译版本为Mint 11(基于Ubuntu), 一般Ubuntu发行版的glibc配备非常高. 但是上文中的发布的Linux版本为CentOS 5.8

使用/lib/libc.so.6 查看libc版本为2.5, 远远低于开发环境的2.11

GNU C Library stable release version 2.5, by Roland McGrath et al.
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-51).
Compiled on a Linux 2.6.9 system on 2012-02-21.
Available extensions:
        The C stubs add-on version 2.1.2.
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        GNU libio by Per Bothner
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
        RT using linux kernel aio
Thread-local storage support included.
For bug reporting instructions, please see:
<
http://www.gnu.org/software/libc/bugs.html>.

由于Linux操作系统的特有elf加载顺序. (可以参考此文). 虽然可以很大程度上解决Windows早期版本的dll hell问题, 但是给部署带来了很大难度

一般常见的解决方法是, 找到一个与目标Linux版本及glibc版本一致的Linux, 将代码及依赖包放在之上编译, 完成后再发布.这种方法与Linux下常见软件安装方法类似. 但是对于商用服务器部署步骤来说未免繁琐, 安全性低.

还有一种方法,使用静态链接. 将所有可执行文件文件依赖的静态库, 系统库,全部静态链接到可执行文件中,可以一次性解决这个问题

步骤:

    1. 在gcc链接命令行中添加-static -static-libgcc -static-libstdc++

    2. 将第三方依赖库打开静态链接开关, 将原来链接.so的库,全改为链接.a

    3. gcc对链接库顺序很敏感, 链接库顺序需要按照从前至后为:  项目产生的静态库 > 第三方库静态库 > 系统静态库

    4. 链接时, 若有未解决的symbol, 可以尝试在最后添加-lpthread及-lrt解决

   

在发布版本Linux上运行可能遇到的问题:

terminate called after throwing an instance of 'std::runtime_error'

what(): locale::facet::_S_create_c_locale name not valid

解决方法: 执行之前运行export LC_ALL="C"

目录
相关文章
|
28天前
|
安全 编译器 C++
C++一分钟之-编译时计算:constexpr与模板元编程
【6月更文挑战第28天】在C++中,`constexpr`和模板元编程用于编译时计算,提升性能和类型安全。`constexpr`指示编译器在编译时计算函数或对象,而模板元编程通过模板生成类型依赖代码。常见问题包括误解constexpr函数限制和模板递归深度。解决策略包括理解规则、编写清晰代码、测试验证和适度使用。通过实战示例展示了如何使用`constexpr`计算阶乘和模板元编程计算平方。
41 13
|
29天前
|
Java Linux
Linux上管理不同版本的 JDK
Linux上管理不同版本的 JDK
27 0
|
15天前
|
Linux
查看linux内核版本
在Linux中查看内核版本可使用`uname -r`、`cat /proc/version`、`lsb_release -a`、`cat /etc/*release`、`dmesg | grep Linux`、`hostnamectl`、`kernrelease`(部分系统)、`rpm -q kernel`(RPM系统)或`dpkg -l linux-image-*`(Debian系)。
14 2
|
21天前
|
安全 小程序 Linux
Linux中信号是什么?Ctrl + c后到底为什么会中断程序?
信号在进程的学习中是一个非常好用的存在,它是软件层次上对中断机制的一种模拟,是异步通信方式,同时也可以用来检测用户空间到底发生了什么情况,然后系统知道后就可以做出相应的对策。
|
21天前
|
Ubuntu Linux UED
|
24天前
|
C++ 开发者
C++一分钟之-编译时计算:constexpr与模板元编程
【7月更文挑战第2天】C++的`constexpr`和模板元编程(TMP)实现了编译时计算,增强代码效率。`constexpr`用于声明编译时常量表达式,适用于数组大小等。模板元编程则利用模板进行复杂计算。常见问题包括编译时间过长、可读性差。避免方法包括限制TMP使用,保持代码清晰。结合两者可以解决复杂问题,但需明确各自适用场景。正确使用能提升代码性能,但需平衡复杂性和编译成本。
41 3
|
21天前
|
运维 监控 大数据
部署-Linux01,后端开发,运维开发,大数据开发,测试开发,后端软件,大数据系统,运维监控,测试程序,网页服务都要在Linux中进行部署
部署-Linux01,后端开发,运维开发,大数据开发,测试开发,后端软件,大数据系统,运维监控,测试程序,网页服务都要在Linux中进行部署
|
29天前
|
存储 算法 编译器
程序与技术分享:C++模板元编程简介
程序与技术分享:C++模板元编程简介
19 0
|
29天前
|
存储 JavaScript 前端开发
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)
程序与技术分享:C++程序设计实验考试准备资料(2019级秋学期)