go build 之后的文件放服务器上不能运行,cpu 不同导致?

heqichang
  • 16

main.go 的代码很简单,就是输出 Hello world!, 尝试交叉编译。

package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world")

}

本地开发用的 mac 系统,服务器ubuntu x86_64,尝试过以下 build 命令交叉编译

GOOS=linux GOARCH=amd64 go build main.go

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go 

在服务器上都不能运行,当然文件已改 777 了,报 Illegal instruction (core dumped)

也在本地尝试在 docker golang 的容器里编译,放服务器依然不能运行,报相同错误。

在服务器上下载 docker golang 容器,在服务器上直接编译,可以运行。然后,把服务器上的下载下来,本地 docker golang 容器里也无法运行,报 Trace/breakpoint trap 。

是因为本地和服务器的 cpu 不同导致编译的程序无法直接运行吗?本地是 cpu 是 Core ,服务器是 Xeon


提供更多的细节参考:

服务器是 google cloud 的 vm。

两边用过同样的 docker 镜像 golang:latest,编译之后,在各自端上都可以运行,但是本地编译的不能运行服务端,服务端的不能运行在本地,无论是否在宿主和容器内。

build 好的程序都是通过 ftp 来上传下载的。

服务器都是报 Illegal instruction (core dumped)
本地是报 Trace/breakpoint trap


按照 @东方星痕 的方案可以成功运行了,在本地 docker 里构建并直接打包镜像到服务器上可以运行成功,但是想知道为什么本机直接 go build 的文件不能在服务端运行 ^-^

回复
阅读 4.1k
2 个回答
东方星痕
  • 1.8k

你可以用docker构建,然后在docker里跑。
只要把docker的编译脚本加个构建阶段,就可以打一个docker镜像出来,然后把这镜像部署到你服务器里

FROM golang:alpine AS build-env
ENV GO111MODULE=on
ENV CGO_ENABLED 0
ADD . /go/src/app
RUN  apk --update add git tzdata
WORKDIR /go/src/app
RUN go build -v -o /go/src/app/app cmd/main.go

FROM alpine
COPY --from=build-env /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build-env /go/src/app/app /app/server
WORKDIR /app
EXPOSE 1321
cmd ./server

PS:

  1. 你本地是osx: 所以编译目标GOOS=linux的, 不管在哪编译的你osx都不可能运行。
  2. 如果想在osx运行GOOS=linux的正确方法是:
    2.1 这个在任意系统运行(osx, linux, windows): docker build . -t appName:latest && docker push appName:latest
    2.2 然后在osx运行: docker run --rm appName
  3. 在其它系统要运行这软件也是用 docker run --rm appName 运行。

这就是docker的交付模式。编译和运行都在docker里。


PS:
如果容器编译环境为golang或者golang:alpine,
然后运行的容器环境为: alpine运行不了的话,
可以dockerfile添加:ENV CGO_ENABLED 0 禁用cgo
如果真使用了cgo不能禁用,建议编译和运行都用debain或ubuntu吧

波罗学
  • 765

你服务器装 Go 了吗?在你的服务器上执行 go env 确认下它的环境变量 GOOS 和 GOARCH,看是否和你配置的一样的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏