最近又重新做一个 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")
}
1
12101111 2022-02-21 12:20:37 +08:00
gdb 运行编译出来的程序, 看看是为什么不能运行
盲猜是因为 CentOS7 的内核太老了 |
2
CEBBCAT 2022-02-21 12:33:28 +08:00
可以把复现代码放在 GitHub 上一份吗? go build 可以通过指定文件,也可以指定 package 。我不知道它们之间究竟有没有区别,但我用的一直都是 package 的方式,例如:
go build -o bin/api src/api_gateway |
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' |
4
CEBBCAT 2022-02-21 12:44:29 +08:00
|
5
ch2 2022-02-21 12:45:00 +08:00
用这个试试:
CGO_ENABLED=0 go build -o test -a -ldflags '-extldflags "-static"' . |
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 |
7
Moker 2022-02-21 13:57:42 +08:00
可以看下是不是依赖库有问题
|
8
elechi 2022-02-21 14:02:10 +08:00
goarch 改成 386 试试
|
9
learningman 2022-02-21 14:39:51 +08:00
ldd 在服务器上看下
|
10
liaohongxing 2022-02-21 14:59:25 +08:00
powershell: $Env:GOOS="linux"
powershell: go build 我的机子 win10 64bit , cpu ryzen 2600, 交叉编译很多年,一直没有问题。 |
11
heqichang OP @12101111 线上的 ubuntu 14 ,我没管理员权限,找运维帮我运行的, 输出是 Segmentation fault (core dumped)
|
12
heqichang OP @CEBBCAT 就是个 hello world 程序,以前知道有这个问题,所以这次 go 17.2 版本再试试,结果还是不能运行。阿里云上面的机器没有装 go 开发环境,就是单纯的 ubuntu 14 。 正式开发我们还是有单独的 linux 机器去做编译部署。感谢你提供的链接。
|
13
heqichang OP @Mohanson 嗯,以前运行不成功我也猜测可能和 CPU 有关,不过太底层的知识我不了解。阿里的服务器应该不会老吧,我的 mac 电脑倒是 13 年款的 :doge
|
14
fovecifer 2022-02-21 15:24:24 +08:00
env GOPROXY=https://goproxy.cn GOOS=linux GOARCH=amd64 go build
|
15
BrettD 2022-02-21 15:26:45 +08:00
Ubuntu 14 太老了,glibc 版本都不知道多少年前的
|
16
heqichang OP @liaohongxing 我放我虚拟机里的 linux 运行也没问题,就是放云服务器上运行不成功。我记得之前在 google vm 上的是 intel xeon cpu ,没体验过这种 u
|
19
zhangsanfeng2012 2022-02-21 17:18:24 +08:00
通过什么协议把二进制文件传到服务器上的?有 FTP 吗
|
20
Reficul 2022-02-21 17:35:53 +08:00
2.6 老内核 Go 的系统调用不一样,你用老版本的 Go 试试看(比如 1.6 ),如果可以运行可能就是这个原因。
|
21
zsj950618 2022-02-21 18:45:36 +08:00 via Android
|
22
gamexg 2022-02-21 18:50:20 +08:00 via Android
我碰到过非常老的 linux 不能运行交叉编译的文件,印象是依赖库问题。
不过项目本身会有韵味那边在线上环境再次编译才会上线,运行没问题,所以没在研究。 |
23
adoal 2022-02-21 19:27:34 +08:00 via iPhone
试试老版本的 go
以前我在新系统里非交叉编译的拿到 centos5 上不能运行,查了一下因为 kernel API 变动而不兼容,于是降级 go 版本搞定 |
24
sakishum 2022-02-21 19:30:25 +08:00
楼主,之前碰到过类似问题,参见
|
25
sakishum 2022-02-21 19:30:55 +08:00
|
26
heqichang OP @zhangsanfeng2012 嗯,FTP 传的
|
28
eudore 2022-02-22 08:53:55 +08:00
缺少静态编译参数
|
29
zhangsanfeng2012 2022-02-22 08:57:48 +08:00 via Android
@heqichang 是不是用 ascii mode 传的,换成 binary mode 上传试试
|
30
heqichang OP @zhangsanfeng2012 我擦,结案了,可以运行了,还真是 FTP 的鬼,我用的 FileZilla ,设置里如果传的文件没有扩展自动转 ascii ,所以文件被损坏了。我怎么也没想到是它是它是它 :doge
|