V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
acbot
V2EX  ›  Go 编程语言

go 开发的软件移植转换为其他语言

  •  
  •   acbot · 2022-02-23 14:13:40 +08:00 · 2540 次点击
    这是一个创建于 764 天前的主题,其中的信息可能已经有所发展或是发生改变。

    go 开发的软件编译后一般相对都比较大,go 有没有类似 Java JDK/JRE 或者是 c/c++ 运行库这样的东西,这样是不是就可以减小一些编译后的体积,特别是有多个 go 编译后的文件。由于嵌入式设备存储空间有限,想把 go 开发的项目移植转换成 c/c++, 是不是 只要 go 用到的库有 c/c++ 版本就可以完成移植转换,有没有工具能直接把 go 代码转换成 c 代码 然后编译。或者是这样的软件参考 go 项目思路直接重新实现就可以了,没有必要转换。

    27 条回复    2022-02-25 20:49:45 +08:00
    dzdh
        1
    dzdh  
       2022-02-23 14:33:30 +08:00
    嵌入式? tinygo

    编译参数 -ldflags "-s -w" ?

    upx ?
    Buges
        2
    Buges  
       2022-02-23 14:43:25 +08:00 via Android
    gccgo ?不过那是 go 语言的 gcc 后端实现,估计也不能满足你的要求。
    acbot
        3
    acbot  
    OP
       2022-02-23 15:52:36 +08:00
    @dzdh
    @Buges

    主要是体积问题, 我就是有点疑惑为什么 go 不像 c/c++ ,java 这些语言 把运行库(运行环境)和程序本身代码分离而非要编译到一起。
    dzdh
        4
    dzdh  
       2022-02-23 16:20:14 +08:00
    @acbot
    因为是自举类型的编译语言?依赖本身就少。

    就这么设计的吧- -

    一个 go 程序编译后只依赖(linux):

    linux-vdso.so.1 / libpthread.so.0 / libc.so.6 / lib64/ld-linux-x86-64.so.2
    BrettD
        5
    BrettD  
       2022-02-23 16:32:10 +08:00 via iPhone
    为什么要用 Go 做嵌入式编程?
    mekingname
        6
    mekingname  
       2022-02-23 16:35:33 +08:00
    @acbot 放在一起才能实现:一次编译,到处运行。

    否则别人要运行你的程序还得安装一个运行环境,太麻烦了。
    acbot
        7
    acbot  
    OP
       2022-02-23 16:38:04 +08:00
    @BrettD 这个得问作者,我想他是考虑跨平台得关系吧。 我们是因为有这个现成的成熟项目,现在也能在目标平台上运行只是它一个程序感觉都比整个系统大了,现在是看有没有方法能缩小体积,没有方法就智能全部重实现。
    acbot
        8
    acbot  
    OP
       2022-02-23 16:40:43 +08:00
    @mekingname 我的意思是编译的时候可以提供一个选项 静态打包或者是动态打包, 如果一个系统运行一个 go 的执行文件可能看不出来区别 但是 如果有多个 go 使用动态打包肯定是可以减少体积的,整个时候就有必要了啥,我个人觉得整个是跨平台语言一个通病就是不分离的话打包后都很大
    adoal
        9
    adoal  
       2022-02-23 16:44:25 +08:00   ❤️ 4
    动态链接库的依赖管理是个很复杂的事。Go 的设计目标之一就是避开业界著名的 DLL hell 问题,所以用了全静态链接,必然会导致单个输出变大。这是它的 trade off ,不是缺陷。你所遇到的这种业务场景不是 Go 的目标场景。换语言吧。

    对了,说到 C ,在嵌入式环境里也有一种全静态的构建方式叫 busybox ,具体做法就是把多个不同程序的源代码稍作改造后拧在一起,通过单一的 main 根据 argv[0]的名字来决定其行为,编译安装好后 ln -s 创建多个名字的软链接。busybox 是全静态的,实际上比每个程序单独编译后加起来要小。不过依赖库太复杂时就不适合用 busybox 了。
    BrettD
        10
    BrettD  
       2022-02-23 16:49:34 +08:00 via iPhone
    @acbot Go 的静态编译设计不适合你的这个嵌入式应用场景,换 C/C++/Rust 比较合适
    qieqie
        11
    qieqie  
       2022-02-23 17:13:08 +08:00
    因为 go 开发的软件基本上都是源码依赖的标准库和第三方库,从这点来说和依赖 header only 库的 C/C++并无不同,而且理论上源码依赖的情况下链接器是可以做到更好的代码体积优化的。
    如果有很多可执行文件共享基础库的情况下,可以写一个可执行入口来执行子程序,链接器会帮你把二进制体积优化到最小的。
    acbot
        12
    acbot  
    OP
       2022-02-23 17:20:09 +08:00
    @adoal
    @BrettD 整个项目就是用 go 做的,尴尬的问题就在这里,有知道作者怎么想的。
    Rwing
        13
    Rwing  
       2022-02-23 17:23:04 +08:00
    @acbot 考虑一下.NET ? 既可以把运行时编译在一起,也可以分开,还跨平台,嵌入式也不再话下 🙂
    devcat9
        14
    devcat9  
       2022-02-23 17:26:02 +08:00 via iPhone
    要不要考虑下 Rust
    acbot
        15
    acbot  
    OP
       2022-02-23 17:32:06 +08:00
    @Rwing
    @devcat9 现在在想办法看能不能缩小,不行的话可能会考虑其他语言重做。
    adoal
        16
    adoal  
       2022-02-23 17:47:24 +08:00 via iPhone
    先 strip 一下
    halfdb
        17
    halfdb  
       2022-02-23 18:06:50 +08:00 via Android
    go 也可以编译成 c 兼容的动态链接库的形式吧。不能满足 lz 的需求吗?
    https://chai2010.cn/advanced-go-programming-book/ch2-cgo/ch2-09-static-shared-lib.html
    feather12315
        18
    feather12315  
       2022-02-23 18:09:07 +08:00 via Android
    @acbot #3 不分开是因为他就这么设计的
    shynome
        19
    shynome  
       2022-02-23 18:10:40 +08:00
    acbot
        20
    acbot  
    OP
       2022-02-24 08:41:30 +08:00
    @halfdb
    @shynome 如果项目多了,这样会不会变得更大!
    shynome
        21
    shynome  
       2022-02-24 09:34:32 +08:00 via Android
    @acbot 看项目,共享的 std 动态库有 30M ,共享状态下的 http server 大小是 2M ,默认编译有裁剪的大小则是 11M ,hello-world 的区别则是 20K 和 6M ,实践下看哪种方式更适合
    Kinnice
        22
    Kinnice  
       2022-02-24 09:37:29 +08:00
    upx 压缩一下。
    acbot
        23
    acbot  
    OP
       2022-02-24 09:59:19 +08:00
    @shynome
    @Kinnice 我都试试,谢谢
    lysS
        24
    lysS  
       2022-02-24 11:45:38 +08:00
    你的什么嵌入式?有操作系统嘛?有操作系统的话我觉得 go 的编译大小不算是问题把?
    lysS
        25
    lysS  
       2022-02-24 11:47:58 +08:00
    对了,编译时加上 `-ldflags "-s -w"` 大概可以减少一半的体积
    acbot
        26
    acbot  
    OP
       2022-02-24 12:54:43 +08:00
    @lysS 谢谢,不知道 `-ldflags "-s -w"` 再加 #22 upx 方法能不呢个达到预期!
    xsen
        27
    xsen  
       2022-02-25 20:49:45 +08:00
    -ldflags "-s -w" + upx 之后,大小可以缩小到 25-30%
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5824 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 01:55 · PVG 09:55 · LAX 18:55 · JFK 21:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.