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


    最近页游开放平台比较多, 每个平台要求的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"

  • 相关阅读:
    Oracle什么时候需要Commit
    Oracle数据库SQL优化
    事务的四个特性(ACID)
    MySQL的两种存储引擎storage engine特点和对比
    MySql绿色版下载,安装,配置详解
    Unsupported major.minor version 51.0
    linux服务器下添加字体
    java日期比较,日期计算
    微信公众号开发保持用户登录状态思路
    本机搭建外网web服务器
  • 原文地址:https://www.cnblogs.com/lidabo/p/4368489.html
Copyright © 2020-2023  润新知