关于 Linux 编译生成可执行文件后打包移植的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
yang3121099
V2EX    Linux

关于 Linux 编译生成可执行文件后打包移植的问题

  •  
  •   yang3121099 2022-11-03 15:54:11 +08:00 3425 次点击
    这是一个创建于 1076 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大哥好,我是大数据和人工智能方向研一在读,项目要用到一个 Github 工具进行数据预处理,应该是和 C 语言编译相关的,了解不多,想请教各位大哥

    问题是这样的

    github 下载以后需要编译生成可执行文件,目前也可以正常使用,但是我需要把它移植到另一个服务器上,新的服务器是学校提供的华为云,并没有 sudo 权限,很多 apt-get 命令应该无法安装,所以想请教一下这种情况下是否有办法打包封装移植呢,就像 Windows 下面 c 语言生成 exe 文件这种拿走就用

    我搜索了一些网页但是没有这方面的介绍,我猜测是必须在每一个新的环境里面配置后重新编译生成才行吗,否则 github 直接给一个可执行的包不就行了哈哈哈

    但是也感觉如果变成一个二进制文件,是否能脱离依赖进行运行呢?那如果不行的话,有没有绕过 sudo 权限的方法啊,我看华为云有一个自定义镜像绕过 apt-get的方法,但是也不知道行不行,没有实际部署的经验,特来请教,谢谢各位大哥

    参考的链接如下:Github

    第 1 条附言    2022-11-05 11:54:29 +08:00

    感谢各位大哥的帮助,这个问题已经解决了,总结一下给后人参考吧,因为我把两边的版本都选的是Ubuntu18.04,大家说的这几个方法应该都可以移植,最后使用的so库和修改~/.bashrc路径

    背景补充: 实验室是有深度学习服务器的,之前有一次找学长申请sudo权限被婉拒,这次是自己的课程作业不是实验室的项目,需要占用几百G空间和显卡资源,就不好意思再去申请了用公共资源了。于是我使用了阿里云的免费试用但只有100G空间,好在有sudo权限能编译这个预处理文件,但没有办法对我500G的原始文件直接处理,近来华为云与学校有合作,课内发了数百元代金券可以使用ModelArts框架和V100显卡,云盘也可以扩容到2TB比较方便,缺点就是没有公网,没有apt-get,没有sudo,寄人篱下有点难受但考虑到以后也要部署应用到其他的环境,就发了这个帖子询问大家

    首先查看两边的ldd --version发现一致,尝试使用no-shared全静态连接但是失败了,安装musl后指定CC运行./configure是可以的,但是make的时候就会说在某个 .h中导入了某个外部的 .so 失败了,推测可能是和这个Github分成了四个模块和框架的总分结构有关?多次尝试后就放弃直接的静态连接了,发现exodus可以直接ssh连接另一台服务器然后导入依赖,就去尝试,但发现华为云这个深度学习框架内不允许ssh密码连接,也许密钥的ssh是可以的,暂且放弃了。

    转头尝试docker,发工单后华为工程师告诉我导入使用docker不需要权限,就开始学习,但也发现了查看和打包.so的方法,于是直接使用 ldd name查看依赖,打包依赖库的脚本可以参考ldd.sh帖子,然后在另一环境修改~/.bashrc即可

    就像各位所言,这样操作的可行性是建立在glibc版本和Ubuntu版本一致的基础上,如果要移植到其他平台可能要寻找更通用的方法。

    再次感谢各位 有什么问题或建议还请留言 @yanqiyu @ysc3839 @tool2d @yyttrr @libook @weidaizi @ch2 @dynos01 @churchill @felixlong @microxiaoxiao @julyclyde @hsfzxjy @kenvix @ferstar @adoal @yanqiyu @tomychen @FrankHB @weidaizi @Inn0Vat10n @chai2010 @cattyhouse

    29 条回复    2022-11-04 17:34:36 +08:00
    yanqiyu
        1
    yanqiyu  
       2022-11-03 15:59:10 +08:00
    选择基本上有:
    - 容器化
    - Appimage
    - 除了 libc 尽可能静态链接 (比如 vscode 的二进制分发)
    - 带一个 prefix ,带着库打包,设置环境变量或者 rpath 来运行
    ysc3839
        2
    ysc3839  
       2022-11-03 16:06:48 +08:00
    依赖库都别用系统的,自己编译链接,可以静态链接,也可以 so 一起打包带走。
    其实跟 Windows 下的区别就是谁来提供这些库,Windows 和 macOS 的惯例是各种依赖库都由程序自己打包。
    tool2d
        3
    tool2d  
       2022-11-03 16:10:07 +08:00
    具体看依赖库了,一般简单的 C 程序,跨 linux 几个版本运行都可以。

    实在不行你本地安装一个和服务器环境一模一样的虚拟机,本地编译 elf 后再上传也行。

    唯一的问题是如果 AI 的话,肯定和 python 相关,如果是用 python setup 之类编译的 so ,那就和 py 运行版本直接绑定了。
    yyttrr
        4
    yyttrr  
       2022-11-03 16:18:43 +08:00
    随便找个星星多的项目,release 里面都会同时提供多个平台的包
    amd64 arm64 windows darwin 等等
    通过 cicd 解决吧,多编译出来不同环境的二进制包
    libook
        5
    libook  
       2022-11-03 16:20:44 +08:00
    程序可能会依赖系统的内核 API 、安装的动态链接库 API 。
    Windows 下面涉及到动态链接库可能也不是拿走就能用的。
    大部分程序使用的是内核的通用 API ,一般只需要注意平台一样就可以,比如 x86-64 平台之间大多是兼容的。
    动态链接库如果目标系统上没有装,你就得跟应用程序一起带过去(包括动态链接库所依赖的其他动态链接库),然后好像可以使用 LD_LIBRARY_PATH 环境变量添加你的库所在的位置。我没试过,你可以探索一下。
    weidaizi
        6
    weidaizi  
       2022-11-03 16:20:48 +08:00
    #1 @yanqiyu 基本答完了,我补充一个注意事项:当选择 3 ,4 的时候,要注意一下 libc 的版本,保证编译机器上的版本 <= 生产环境的版本
    ysc3839
        7
    ysc3839  
       2022-11-03 16:22:39 +08:00
    看了下你给的自定义镜像的链接,好像就是弄个 Docker 镜像?那弄一个试试就知道了。
    ch2
        8
    ch2  
       2022-11-03 16:33:45 +08:00
    容器是最稳的,裸而且大的二进制没啥意义
    dynos01
        9
    dynos01  
       2022-11-03 16:37:13 +08:00
    针对这样的情况首先考虑静态编译吧,用 musl 。这样正常情况下都能满足你的需要。 以下是参考命令:
    '''
    git clone --recursive https://github.com/CESNET/nemea
    ./bootstrap.sh
    CC="musl-gcc -static" ./configure --enable-repobuild --prefix=/usr --bindir=/usr/bin/nemea --syscOnfdir=/etc/nemea --libdir=/usr/lib64
    make
    '''
    我没有自己测试,但正确安装 musl 后应该能跑通。这样得到的二进制基本上跨平台都没问题。
    dynos01
        10
    dynos01  
       2022-11-03 16:37:42 +08:00
    s/静态编译 /静态链接,手滑了
    churchill
        11
    churchill  
       2022-11-03 16:46:11 +08:00
    felixlong
        12
    felixlong  
       2022-11-03 16:49:44 +08:00
    你这个程序本身看上去就需要 root 权限来运行。还是想办法拿到 root 权限吧。
    yang3121099
        13
    yang3121099  
    OP
       2022-11-03 16:55:57 +08:00
    谢谢各位大哥,我大概明白了

    就是把现有的 prefix 和 so 库也复制过去然后改 path
    或者直接全改成静态链接+通用的 libc 直接拿去就用

    我也去了解一下 docker ,以前只听在鹅厂实习的师兄提过是为了提交的代码安全什么的,但我也不知道是啥,感觉挺高级的,之前印象中一直觉得 docker 就是 mac/linux 的任务栏哈哈哈

    之前学的 c 语言都是点击自动 compile-run 的,帖子里的这几个名词我慢慢去看,现在进行的 AI 训练模型也是,整天看论文看数学公式然后代码改几行,就丢给显卡看学习曲线,更基础一些的编程原理就啥也不知道了,感觉根基多少不太牢

    如果必须 sudo 的话只能两个服务器了,因为需要新的环境提供显卡资源

    多谢各位的回复

    @yanqiyu
    @ysc3839
    @tool2d 确实 最后要转到 python 怎么把深度学习的模型打包是我的下一个问题哈哈哈
    @yyttrr
    @libook
    @weidaizi
    @ch2
    @dynos01
    @churchill
    @felixlong
    microxiaoxiao
        14
    microxiaoxiao  
       2022-11-03 16:55:57 +08:00 via Android
    静态编译最靠谱,ABI 不变就能运行,注意华为的是不是 arm 的。动态库都有可能有兼容性问题
    yang3121099
        15
    yang3121099  
    OP
       2022-11-03 16:57:13 +08:00
    @microxiaoxiao 好的 我先试一下静态编译,然后学一下 docker 吧,这个 so 看起来考虑的因素有点多哈哈哈
    julyclyde
        16
    julyclyde  
       2022-11-03 17:46:22 +08:00
    @weidaizi 不是简单的小于等于版本的问题。兼容也是有一定范围的不是无限的
    julyclyde
        17
    julyclyde  
       2022-11-03 17:46:48 +08:00
    @yang3121099 容器也需要 root 权限

    别听鹅厂的人吓咋呼,技术差得很
    hsfzxjy
        18
    hsfzxjy  
       2022-11-03 17:49:01 +08:00 via Android
    exodus 可以试试
    kenvix
        19
    kenvix  
       2022-11-03 18:32:55 +08:00
    容器化也得先用 root 装个容器 runtime 啊
    ferstar
        20
    ferstar  
       2022-11-03 19:07:35 +08:00
    炼丹童子啊,conda 了解下
    adoal
        21
    adoal  
       2022-11-03 20:01:33 +08:00
    如果是为学校做的工作,或者课业要求,那跟学校里负责这事的人提出你的合理诉求。
    如果不是……那为啥要安装到你没有 root 权限的属于学校的服务器上。
    yanqiyu
        22
    yanqiyu  
       2022-11-03 21:15:19 +08:00
    @kenvix podman 这类 root 容器本身也不需要 suid helper 所以用户权限就能跑起来?虽然还是要有 root 才能 assign 的 subgid/subgid range
    tomychen
        23
    tomychen  
       2022-11-03 21:24:09 +08:00
    可能比较适用的就是 musl + full static 编译了

    但是,即便这样了,可能还会遇到平台不一样的问题 arm/x86/x86_64

    主要还得看代码里是不是完全能用 musl 代替
    FrankHB
        24
    FrankHB  
       2022-11-03 21:34:55 +08:00
    又不是没源码,直接本地重新编译链接会死?
    还是说服务器连 gcc 这种都没有?
    会死的话投诉服务器管理员,丫个生产环境都残的。
    weidaizi
        25
    weidaizi  
       2022-11-03 22:08:21 +08:00
    @julyclyde 你说的对!我刚刚的回答不严谨
    Inn0Vat10n
        26
    Inn0Vat10n  
       2022-11-03 22:26:48 +08:00
    补充一个,编译时最好带上目标机器的 cpu 指令集 flag ,不然全静态编译还是可能会挂掉
    chai2010
        27
    chai2010  
       2022-11-04 10:16:38 +08:00
    以前 windows 用户有个 DLL 地狱的说法。想避免动态库依赖地狱就尽量全静态编译。
    cattyhouse
        28
    cattyhouse  
       2022-11-04 17:33:27 +08:00
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     905 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 21:58 PVG 05:58 LAX 14:58 JFK 17:58
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86