V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
solider245
V2EX  ›  Linux

不懂就问:其他电脑编译好的二进制文件可以直接到其他机器使用吗?

  •  1
     
  •   solider245 · 2020-11-01 14:18:35 +08:00 · 7479 次点击
    这是一个创建于 1484 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,经常遇到很多文件因为网络问题无法安装。
    那么,我可以在其他电脑将二进制文件编译好,然后再通过网盘工具或者其他下载工具,将其下载到本地电脑直接使用吗?

    比如我有一台香港的 ubuntu 服务器,编译安装好了一个软件,然后将其打包,我本地有一台电脑,直接将软件下载到本地,然后解压缩直接使用。可以这样吗
    38 条回复    2020-11-02 16:32:25 +08:00
    misaka19000
        1
    misaka19000  
       2020-11-01 14:24:25 +08:00   ❤️ 1
    可以的,这个分为两种

    1. 两台机器的操作系统、CPU 指令集一致,这样能保证可执行文件的结构以及相应的指令集符合目标机器的要求
    2. 如果不符合上一个条件,可以使用交叉编译
    VDimos
        2
    VDimos  
       2020-11-01 14:28:10 +08:00 via Android
    你要处理一些环境变量之类的,不嫌麻烦完全可以
    skydiver
        3
    skydiver  
       2020-11-01 14:30:57 +08:00   ❤️ 1
    打包成 deb 包,包管理器会处理依赖问题
    unicloud
        4
    unicloud  
       2020-11-01 14:33:18 +08:00 via iPhone
    那得看在编译时有没有依赖特定的环境变量.
    Osk
        5
    Osk  
       2020-11-01 14:40:43 +08:00 via Android   ❤️ 1
    可以的:
    如果 CPU 架构不同,可以交叉编译。

    同 cpu 架构 + 不同操作系统:可以交叉编译。

    同 cpu 架构 + 同操作系统 + 不同发行版:需要注意运行库版本的问题,方法也挺多的,比如静态编译,或者暴力点,用 ldd 等工具把依赖的 so 文件一起拷走。

    同 cpu 加构 + 同操作系统发行版:最简单了,记好安装了哪些包,这边对应着装上就好,建议打包成 deb/rpm 等该发行版的包,更好安装和管理。
    mikeguan
        6
    mikeguan  
       2020-11-01 15:03:04 +08:00 via Android
    直接打 docker 镜像
    solider245
        7
    solider245  
    OP
       2020-11-01 15:05:48 +08:00
    @misaka19000
    @Osk 简单来说,我在远程服务器上的二进制文件,将其打包成 deb 包。然后下载到本地,之后再将 deb 包解压安装即可?
    Jirajine
        8
    Jirajine  
       2020-11-01 15:28:22 +08:00 via Android
    静态编译 or docker or snap/flatpak/appimage
    user8341
        9
    user8341  
       2020-11-01 15:45:21 +08:00
    打包成 deb 用什么? checkinstall 吗?
    irytu
        10
    irytu  
       2020-11-01 15:56:46 +08:00 via iPhone
    1. 不同 CPU 架构下,需要交叉编译,用可以生成 target 二进制的 toolchain

    2. 相同架构下,注意链接的动态库不能丢
    icyalala
        11
    icyalala  
       2020-11-01 15:58:03 +08:00
    @solider245 前提是编译时使用的指令集在服务器和本地是通用的,比如两边都是 x64 的,也没用什么 avx512 之类的可能有一边不支持的指令。还有依赖的动态库两边也要兼容。
    Nimrod
        12
    Nimrod  
       2020-11-01 16:17:31 +08:00 via Android
    @mikeguan 不同架构下的 docker 也不能直接跑。。
    mikeguan
        13
    mikeguan  
       2020-11-01 16:26:05 +08:00 via Android
    @Nimrod 那就把 dockerfile 复制过来
    msg7086
        14
    msg7086  
       2020-11-01 17:11:55 +08:00
    同指令集(如 x86_64 ),同发行版同版本(如 Ubuntu 20.04 ),可以直接搬过来用。
    当然前提是本机装齐依赖。

    否则至少需要静态编译,或者把依赖的库版本一起复制过来。如果编译环境太新,运行环境太久,还要涉及到内核兼容性还有 libc 兼容性等等,出问题概率很大。

    这就和 Windows 上的软件一样,你编译完的 exe 也不是拷出来就能用的,一样需要备齐 dll 依赖。然后新的软件老的系统可能跑不起来。
    XiLingHost
        15
    XiLingHost  
       2020-11-01 18:46:42 +08:00
    @Nimrod 那就直接打 OVA 包
    Tumblr
        16
    Tumblr  
       2020-11-01 18:51:21 +08:00   ❤️ 1
    这个标题 shock 到我了。。。
    我们平时下载的 binary file,不基本上都是别人在别的电脑上编译好的么。。。
    forgottencoast
        17
    forgottencoast  
       2020-11-01 19:04:45 +08:00
    @Tumblr 我以为第一条回复就会是你这样的,结果到最后才有一条,看来是我不太了解背景。
    Tumblr
        18
    Tumblr  
       2020-11-01 19:26:51 +08:00
    @forgottencoast #15 看到标题,震惊之后我想可能是楼主想问交叉编译之类的吧,结果看了楼主的表述,确实是第一反应想到的。
    lscexpress
        19
    lscexpress  
       2020-11-01 19:40:01 +08:00   ❤️ 1
    希望楼主下次叫不懂就查或者搜索,这种烂问题已经问烂了
    solider245
        20
    solider245  
    OP
       2020-11-01 19:45:34 +08:00
    @msg7086 原来是这样,简单来说就是 a 机器上的 bin 文件放到 b 机器上,只要 b 的环境依赖和 a 一样,那就可以直接使用。
    @lscexpress 很尴尬的是,很多问题搜索后找不到,但是来论坛上问反而有人回答。可能是中文环境问题。一般报错或者简单的英文问题直接搜英文就有答案而且还很专业。搜索中文的,99%都是营销答案,抄的有时候还是很古老的东西。
    看中文的问题经常让我怀疑我们中国人编程是真的不行。但是一到论坛上提问,却发现论坛上的回答又快又好,而且还很细致。以至于做一个答案汇总甚至都可以出一篇技术小短文了……
    haohaolee
        21
    haohaolee  
       2020-11-01 22:12:29 +08:00
    这个问题涉及到的因素太多了,建议你先保证两边的操作系统一致,比如 ubuntu xx.xx x86_64,然后试着先编译出来看看。不行的话具体问题具体分析
    crayygy
        22
    crayygy  
       2020-11-01 22:26:34 +08:00 via Android
    当然可以,一个简单的例子就是 Android 和 iOS 本身并没有办法在自己的平台上编译出二进制,而是依赖其它桌面平台来编译二进制来使用。
    只是要处理好平台依赖,所以类似于 Windows Linux 和 Mac 之间,或者 ARM X86 可能会有些平台特有的 ABI 接口问题(也是可解决的),但同一个平台理论上还是比较好处理依赖的
    owt5008137
        23
    owt5008137  
       2020-11-01 23:08:14 +08:00 via Android
    所有的依赖 ABI 兼容就可以。至于怎么知道 ABI 是否兼容,linux 内核版本升级
    owt5008137
        24
    owt5008137  
       2020-11-01 23:11:16 +08:00 via Android
    接上条。没写完不小心按了回复。
    linux 和 gcc,glibc 这十几年的升级都是 ABI 兼容的,其他的我不清楚,得看依赖的库了。其他的库如果能全部静态链接大概率也行。
    systemcall
        25
    systemcall  
       2020-11-01 23:21:18 +08:00 via Android
    感觉用 docker 就行了
    只要你的电脑可以运行 docker,不管是 Windows 还是 macOS 、Linux 都可以。当然,都得是 AMD64 架构。你要是用的 Aarch64,应该会弄交叉编译
    下载的二进制文件有时候会有些稀奇古怪的问题,不会搞的话就用 docker,省事
    systemcall
        26
    systemcall  
       2020-11-01 23:24:58 +08:00 via Android
    你要是在自己的电脑上装个一样的系统。依赖之类的弄好,拷过来基本上不会有什么问题
    3dwelcome
        27
    3dwelcome  
       2020-11-01 23:25:16 +08:00 via Android
    我开开心心的交叉编译,结果运行的时候来一个 kernel too old,其他 abi 都对,给我跳这个,心累。
    xiadong1994
        28
    xiadong1994  
       2020-11-02 01:54:49 +08:00 via iPhone
    @Tumblr 我的第一反应也是这个,楼主不会认为装的二进制包都是本地编译的吧
    Bromine0x23
        29
    Bromine0x23  
       2020-11-02 09:08:11 +08:00
    可以,但不是随便就可以
    p1gd0g
        30
    p1gd0g  
       2020-11-02 09:15:44 +08:00
    话说上次 go 编译遇到 glibc 版本无法运行的问题。
    no1xsyzy
        31
    no1xsyzy  
       2020-11-02 09:22:44 +08:00
    @3dwelcome 这就是 docker 出场的时候了
    newmlp
        32
    newmlp  
       2020-11-02 09:36:07 +08:00
    一个程序要运行起来需要很多操作系统相关的东西,
    ungrown
        33
    ungrown  
       2020-11-02 10:04:18 +08:00
    @msg7086 #14 相邻发行版直接拷过去试一试保不齐也能用
    我自己的 VPS 和家里服务器之间这样弄过几次,跨越的版本是 16 和 18
    缺了依赖的库有时可以手动装上,PPA 或者直接网站上下下来扔到路径里
    ungrown
        34
    ungrown  
       2020-11-02 10:08:11 +08:00
    @solider245 #20 中文资料很少的
    因为英文社区异常活跃
    很多非英语母语的人遇到问题如果母语资料不够用也会硬着头皮去英语社区用英语询问交流
    久而久之全世界的人都在向英语社区共享问题、答案、经验、讨论、猜想、验证……
    中文用户当然也逃不掉
    所以直接英文搜索是最可能找到具体解决方案的,再不济直接用英文开贴询问
    flyico
        35
    flyico  
       2020-11-02 10:13:53 +08:00
    只要没有特别的依赖,大部分是没问题的,我曾经在 centos6 上编好的 binary,拷到 Ubuntu18.04 上能直接运行
    libook
        36
    libook  
       2020-11-02 10:36:42 +08:00   ❤️ 2
    程序需要关心的大体是这几层:硬件指令集、操作系统 API 、依赖(如动态链接库)、运行时(Runtime)、环境配置(如环境变量)。
    如果你两台机器这几层都互相兼容,那么你从一台机器编译的程序可以直接在另一台机器运行。

    网络问题可以尝试用代理解决,或者使用镜像源。
    服务型软件可以考虑用容器方案,可以在各个地方使用极度相同的环境。
    yklaxds
        37
    yklaxds  
       2020-11-02 13:53:22 +08:00 via Android
    打包成 appimage 就可以了。
    CodeCodeStudy
        38
    CodeCodeStudy  
       2020-11-02 16:32:25 +08:00
    用 Golang,可以交叉编译
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3811 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:00 · PVG 09:00 · LAX 17:00 · JFK 20:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.