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

go 语言交叉编译后无法运行

  •  
  •   heqichang ·
    heqichang · 2022-02-21 12:04:55 +08:00 · 4392 次点击
    这是一个创建于 785 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近又重新做一个 go 项目,但是我本地是 mac ,放阿里云 linux 还是没法运行,这是我很早以前在 sf 上的一个提问:go build 之后的文件放服务器上不能运行,cpu 不同导致?,当时通过 docker 打包在容器里去运行,但是没人解释出根本的原因。

    编译命令:

    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o test main.go
    

    编译的代码也很简单:

    func main() {
    	fmt.Println("hello world")
    }
    
    31 条回复    2022-02-22 20:28:41 +08:00
    12101111
        1
    12101111  
       2022-02-21 12:20:37 +08:00
    gdb 运行编译出来的程序, 看看是为什么不能运行
    盲猜是因为 CentOS7 的内核太老了
    CEBBCAT
        2
    CEBBCAT  
       2022-02-21 12:33:28 +08:00
    可以把复现代码放在 GitHub 上一份吗? go build 可以通过指定文件,也可以指定 package 。我不知道它们之间究竟有没有区别,但我用的一直都是 package 的方式,例如:

    go build -o bin/api src/api_gateway
    CEBBCAT
        3
    CEBBCAT  
       2022-02-21 12:44:12 +08:00
    各个组件的版本号贴一下,我 Google 到一个 issue ,那边好像判断下来是 CPU 太老了,编译的时候使用了新的指令集,造成不兼容

    macOS 、Aliyun 、Google Cloud 的 go env 、uname -a 。如果方便的话,sysctl 也可以贴一下,比如 sysctl -a | grep 'machdep.cpu'
    CEBBCAT
        4
    CEBBCAT  
       2022-02-21 12:44:29 +08:00
    ch2
        5
    ch2  
       2022-02-21 12:45:00 +08:00
    用这个试试:
    CGO_ENABLED=0 go build -o test -a -ldflags '-extldflags "-static"' .
    Mohanson
        6
    Mohanson  
       2022-02-21 13:19:02 +08:00   ❤️ 1
    估计 CPU 版本问题. amd64 指令集有不同的版本, 最基础的是基线版本 baseline, 后面还有 v2, v3, v4... 理论上现在你能用到的所有 amd64 cpu 都支持基线版本的指令集, 但是不一定会支持更高版本的指令集(如果你的 CPU 太旧的话). 你在 mac 进行交叉编译, 只告诉了编译器目标操作系统和目标架构, 却没有告诉它目标架构的版本, 那么它很可能用了更高版本的指令.

    https://github.com/golang/go/issues/50589
    Moker
        7
    Moker  
       2022-02-21 13:57:42 +08:00
    可以看下是不是依赖库有问题
    elechi
        8
    elechi  
       2022-02-21 14:02:10 +08:00
    goarch 改成 386 试试
    learningman
        9
    learningman  
       2022-02-21 14:39:51 +08:00
    ldd 在服务器上看下
    liaohongxing
        10
    liaohongxing  
       2022-02-21 14:59:25 +08:00
    powershell: $Env:GOOS="linux"
    powershell: go build

    我的机子 win10 64bit , cpu ryzen 2600, 交叉编译很多年,一直没有问题。
    heqichang
        11
    heqichang  
    OP
       2022-02-21 15:05:56 +08:00
    @12101111 线上的 ubuntu 14 ,我没管理员权限,找运维帮我运行的, 输出是 Segmentation fault (core dumped)
    heqichang
        12
    heqichang  
    OP
       2022-02-21 15:16:57 +08:00
    @CEBBCAT 就是个 hello world 程序,以前知道有这个问题,所以这次 go 17.2 版本再试试,结果还是不能运行。阿里云上面的机器没有装 go 开发环境,就是单纯的 ubuntu 14 。 正式开发我们还是有单独的 linux 机器去做编译部署。感谢你提供的链接。
    heqichang
        13
    heqichang  
    OP
       2022-02-21 15:22:40 +08:00
    @Mohanson 嗯,以前运行不成功我也猜测可能和 CPU 有关,不过太底层的知识我不了解。阿里的服务器应该不会老吧,我的 mac 电脑倒是 13 年款的 :doge
    fovecifer
        14
    fovecifer  
       2022-02-21 15:24:24 +08:00
    env GOPROXY=https://goproxy.cn GOOS=linux GOARCH=amd64 go build
    BrettD
        15
    BrettD  
       2022-02-21 15:26:45 +08:00
    Ubuntu 14 太老了,glibc 版本都不知道多少年前的
    heqichang
        16
    heqichang  
    OP
       2022-02-21 15:28:30 +08:00
    @liaohongxing 我放我虚拟机里的 linux 运行也没问题,就是放云服务器上运行不成功。我记得之前在 google vm 上的是 intel xeon cpu ,没体验过这种 u
    12101111
        17
    12101111  
       2022-02-21 15:39:39 +08:00
    @BrettD go 程序关了 cgo 是不会调 libc 的
    BrettD
        18
    BrettD  
       2022-02-21 16:18:31 +08:00
    @12101111 那估计是内核版本太老,Go 的有些系统调用在旧内核无法正常工作
    zhangsanfeng2012
        19
    zhangsanfeng2012  
       2022-02-21 17:18:24 +08:00
    通过什么协议把二进制文件传到服务器上的?有 FTP 吗
    Reficul
        20
    Reficul  
       2022-02-21 17:35:53 +08:00
    2.6 老内核 Go 的系统调用不一样,你用老版本的 Go 试试看(比如 1.6 ),如果可以运行可能就是这个原因。
    zsj950618
        21
    zsj950618  
       2022-02-21 18:45:36 +08:00 via Android
    gamexg
        22
    gamexg  
       2022-02-21 18:50:20 +08:00 via Android
    我碰到过非常老的 linux 不能运行交叉编译的文件,印象是依赖库问题。
    不过项目本身会有韵味那边在线上环境再次编译才会上线,运行没问题,所以没在研究。
    adoal
        23
    adoal  
       2022-02-21 19:27:34 +08:00 via iPhone
    试试老版本的 go
    以前我在新系统里非交叉编译的拿到 centos5 上不能运行,查了一下因为 kernel API 变动而不兼容,于是降级 go 版本搞定
    sakishum
        24
    sakishum  
       2022-02-21 19:30:25 +08:00
    楼主,之前碰到过类似问题,参见
    heqichang
        26
    heqichang  
    OP
       2022-02-22 08:50:02 +08:00
    @zhangsanfeng2012 嗯,FTP 传的
    heqichang
        27
    heqichang  
    OP
       2022-02-22 08:53:12 +08:00
    @zsj950618
    @sakishum 感谢提供的链接
    eudore
        28
    eudore  
       2022-02-22 08:53:55 +08:00
    缺少静态编译参数
    zhangsanfeng2012
        29
    zhangsanfeng2012  
       2022-02-22 08:57:48 +08:00 via Android
    @heqichang 是不是用 ascii mode 传的,换成 binary mode 上传试试
    heqichang
        30
    heqichang  
    OP
       2022-02-22 09:16:51 +08:00
    @zhangsanfeng2012 我擦,结案了,可以运行了,还真是 FTP 的鬼,我用的 FileZilla ,设置里如果传的文件没有扩展自动转 ascii ,所以文件被损坏了。我怎么也没想到是它是它是它 :doge
    CEBBCAT
        31
    CEBBCAT  
       2022-02-22 20:28:41 +08:00
    @heqichang 你…… hash 都不对比一下的?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2950 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 15:19 · PVG 23:19 · LAX 08:19 · JFK 11:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.