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

转自:战魂小筑, http://www.cppblog.com/sunicdavy/archive/2012/04/20/172108.html


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux上常用的C语言程序开发环境有多种选择,比如gcc、Makefile、Code::Blocks、Eclipse等。下面简单介绍一下gcc和Makefile的安装和使用。 1. 安装gcc gcc是Linux下最常用的编译器之一,它可以编译C、C++程序。安装gcc的命令如下: ``` sudo apt-get install gcc ``` 2. 编写C程序 使用任意文本编辑器编写C程序,比如vim、gedit、nano等。以vim为例,打开终端,输入以下命令: ``` vim hello.c ``` 在vim中输入以下代码: ```c #include <stdio.h> int main() { printf("Hello World!\n"); return 0; } ``` 保存并退出。 3. 编译C程序 使用gcc编译C程序的命令如下: ``` gcc -o hello hello.c ``` 其中,-o选项用于指定输出文件名,hello是输出文件名,hello.c是源文件名。 4. 运行C程序 编译成功后,可以运行C程序,命令如下: ``` ./hello ``` 输出结果为: ``` Hello World! ``` 5. 使用Makefile Makefile是一个自动化编译工具,可以自动化地完成编译、链接等操作。使用Makefile可以简化编译过程,提高效率。 使用任意文本编辑器创建一个名为Makefile的文件,输入以下内容: ```makefile all: hello hello: hello.c gcc -o hello hello.c clean: rm -f hello ``` 其中,all、hello、clean是Makefile中的目标。all是默认目标,即在不指定目标时,会执行all目标。hello目标用于编译hello.c文件,clean目标用于清除编译生成的文件。 在终端中,输入以下命令: ``` make ``` 即可完成编译。如果需要清除编译生成的文件,可以输入以下命令: ``` make clean ``` 以上就是Linux上安装和使用C语言程序开发环境的简单介绍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值