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

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

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

    各位大哥好,我是大数据和人工智能方向研一在读,项目要用到一个 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   ·   实用小工具   ·   2796 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 13:44 · PVG 21:44 · LAX 05:44 · JFK 08:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.