V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mytry
V2EX  ›  程序员

不同版本的 Linux 用同一个二进制文件,有什么需要注意的地方?

  •  
  •   mytry · 2019-05-14 11:53:15 +08:00 · 3247 次点击
    这是一个创建于 2025 天前的主题,其中的信息可能已经有所发展或是发生改变。
    打算把之前的在线代理做一个二进制的版本,不用每次安装都要编译和装一大堆依赖。刚刚试了下把 CentOS 编译的 nginx 二进制放到 Ubuntu 上可以运行,不知道会不会存在一些潜在的问题。

    比如有些机器不支持某些 CPU 高级指令,是不是会出现问题?或者性能是不是自己编译的更高?
    19 条回复    2019-05-15 01:12:57 +08:00
    junjieyuanxiling
        1
    junjieyuanxiling  
       2019-05-14 13:45:13 +08:00 via Android
    主要是依赖和 CPU 架构问题
    xiri
        2
    xiri  
       2019-05-14 14:00:06 +08:00 via Android
    完全静态编译、连接的话,只要 cpu 架构一样应该是没啥问题的,像 go 一样
    PTLin
        3
    PTLin  
       2019-05-14 16:13:42 +08:00
    编译的时候没有高级特性应该没问题,动态链接的话要注意一下依赖问题,不然可能 segment fault。
    FrankHB
        4
    FrankHB  
       2019-05-14 17:31:37 +08:00
    ABI (e.g. libstdc++)
    LD_LIBRARY_PATH/rpath
    内核版本和兼容性 (e.g. ELF section .note.ABI-tag)
    syscall 实现偷工减料的可能性 (e.g. WSL fakeroot)
    zanzhz1101
        5
    zanzhz1101  
       2019-05-14 17:34:51 +08:00
    所以 docker 多好
    mywaiting
        6
    mywaiting  
       2019-05-14 17:37:45 +08:00
    搞个交叉编译啊,这样就没事了~
    zanzhz1101
        7
    zanzhz1101  
       2019-05-14 17:49:38 +08:00
    静态编译就好了吧,基本也都是 x86
    KigKrazy
        8
    KigKrazy  
       2019-05-14 17:51:51 +08:00
    docker 搞起···
    mytry
        9
    mytry  
    OP
       2019-05-14 17:53:08 +08:00
    @zanzhz1101 docker 不太熟~ 用了 docker 可以做到发布一次到处运行吗? IO 性能方面是不是会有损失?
    zanzhz1101
        10
    zanzhz1101  
       2019-05-14 18:09:05 +08:00
    @mytry #9 他是相当于把服务的运行环境打成了一个包,docker 虚拟的是系统资源,io 的话我觉得问题应该不大,估计影响不会大于 5%,我觉得大佬你先考虑下静态编译,但是包会变大不少,然后再考虑 docker 化分支啥的,方便部署,x86 的二进制包基本没啥问题
    iwtbauh
        11
    iwtbauh  
       2019-05-14 18:11:01 +08:00 via Android
    @xiri #2

    静态链接的话会有内核问题。程序将会依赖最低内核版本。
    iwtbauh
        12
    iwtbauh  
       2019-05-14 18:15:01 +08:00 via Android   ❤️ 1
    避免静态链接,一旦静态链接,就会造成很多严重的二进制可移植性问题。

    例如内核依赖的问题。你静态链接的 libc 可能与当前系统其他部分有耦合,更换环境可能导致部分功能异常(例如域名解析相关)。

    最严重的是静态链接的程序无法使用 dlopen 系列函数。对于某些程序可能是致命性的。

    如果提高二进制可移植性?

    1。不要用 -static
    2。libc (如 glibc )绝对不要静态链接
    3。 静态链接 libgcc,libstdc++,libssl,libcrypto,libcurl 等,如果可以,后面几个尽量用自己编译的而不是发行版提供的版本。
    Reficul
        13
    Reficul  
       2019-05-14 18:16:44 +08:00 via Android
    docker 也帮不了内核的坑😂🤣
    FrankHB
        14
    FrankHB  
       2019-05-14 18:23:32 +08:00
    @iwtbauh libc 不要静态链接这点强调得好,我给漏了。(因为没刻意往作大死方向上想。)
    不过这个恐怕还是历史惯性的关系,按道理讲 C 都不提供的功能 libc 就不该多管,libc 本身并没有做系统调用中间层的义务,也不干 loader 什么事。Windows 上 libc/msvcrt 和 kernel32 之类的就是分开的(虽然算上 libc(mt)多版本坑一点都不小就是了)。
    azh7138m
        15
    azh7138m  
       2019-05-14 19:07:00 +08:00 via Android
    ovz 小鸡不能跑 docker 的(
    akira
        16
    akira  
       2019-05-14 19:17:26 +08:00
    32/64 呀
    还有 arm 要不要考虑
    jim9606
        17
    jim9606  
       2019-05-14 19:41:43 +08:00
    如果要跨发行版兼容的话(客户程序分发)可以用一些容器化的打包方案,例如 Snap,Flatpak,非容器化的方案有 appimage,通用性相对差些。这些方案基本上都是用一些手段打包全部依赖。
    服务器应用我觉得 docker 足够解决问题了,除非你要支持的平台用不了 docker(例如 openvz,用 2.6 旧内核的 RHEL/CentOS)
    jinliming2
        18
    jinliming2  
       2019-05-14 23:57:08 +08:00 via iPhone
    架构一样就没什么问题。
    建议静态链接。
    动态链接的话,建议跑起来用 lsof 看一下依赖,然后把所有依赖都拷贝到一个目录下,保持原有目录结构,然后用 chroot 运行。
    qinghon
        19
    qinghon  
       2019-05-15 01:12:57 +08:00 via Android
    楼主是说的 nginx 的编译吗,我觉得直接参照 nginx 的官方 docker 镜像,改编译参数就可以了,这样同样可以做到,缺点就是 ovz
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1336 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:51 · PVG 01:51 · LAX 09:51 · JFK 12:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.