【问题标题】:Go 1.7 Cross Compilation from Windows to Linux/UbuntuGo 1.7 从 Windows 到 Linux/Ubuntu 的交叉编译
【发布时间】:2017-06-26 08:31:11
【问题描述】:

我在 Windows 10 上安装了 GO 1.7。我创建了测试程序,它在 Windows 中完美运行。下一步是尝试使用 Ubuntu 在我的 docker 虚拟机上运行它。

我找到了here 一些关于如何做的信息

set GOARCH=amd64
set GOOS=linux
go tool dist install -v pkg/runtime
go install -v -a std

我在 cmd 中运行第 1 行和第 2 行,没有问题。在第 3 行我有一个错误

go tool dist: open C:\Go\src\pkg\runtime: The system cannot find the path specified.

我手动检查了这个文件夹,并且有一个仅适用于 windows 的运行时

问题是我可以在哪里以及如何为 linux 下载它?或者也许那是我正在做的完全错误的方式......

2017 年 9 月 2 日更新

我按照建议跑了

set GOARCH=amd64
set GOOS=linux
go build -o "myapp"

在我将此文件复制到共享文件夹后,将表单复制到另一个非共享文件夹(以避免here 描述的问题)并执行

root@7dd1655ae5db:/__notshared# ./myapp
bash: ./myapp: cannot execute binary file: Exec format error

下载文件包后检查我的文件

root@7dd1655ae5db:/__notshared# file myapp
myapp: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows

似乎在构建过程中没有创建 linux 可执行文件。

【问题讨论】:

  • 我认为你不需要第三个命令,只需安装std(即go install std)就足够了。

标签: go cross-platform


【解决方案1】:

另一个问题有点老了(从 2013 年开始)。

跨平台支持发展了很多,您只需更改环境变量(GOARCH 和GOOS)并运行go build。

导航到main包的文件夹,然后:

set GOARCH=amd64
set GOOS=linux
go build

您可以像这样更改结果二进制文件的名称:

go build -o "myapp"

请注意,在 Linux 中为 Windows amd64 编译应用程序,一个命令就足够了(在 main 包的文件夹中):

GOOS=windows GOARCH=amd64 go build

这也在博文中得到证实:Dave Cheney: Cross compilation with Go 1.5:

使用 Go 1.5 交叉编译 Go 程序的过程如下:

  1. 将GOOS 和GOARCH 设置为目标operating system and architecture 的值。

  2. 运行go build -v YOURPACKAGE

注意事项

您不必,也不应该运行go install,因为这将编译和安装您的GOPATH 中的包,而这通常是不需要的。进行交叉编译不是为了开发/测试您的应用程序和包。它是生成一个二进制文件,您将在另一个系统/计算机上运行。

go build 不会安装任何东西,它只会生成可执行的二进制文件。详情见What does go build build?

也在博文中确认:Dave Cheney: Cross compilation with Go 1.5:

交叉编译时,应该使用go build,而不是go install。这是go build 优于go install 的少数情况之一。

原因是go install 总是将编译后的包、.a 文件缓存到与源代码根目录匹配的pkg/ 目录中。

【讨论】:

  • 我相信在交叉编译时你仍然需要安装目标平台的标准库。我使用 ie sudo env GOOS=windows GOARCH=amd64 /usr/local/go/bin/go install std 在我的 Ubuntu 上启用 win64 的交叉编译。
  • @ain 不,它没有。在Linux中,你需要做的就是在主包的文件夹中运行GOOS=windows GOARCH=amd64 go build(刚刚验证过)。
  • 会不会是你已经安装了std?在我上次升级 go(到 1.7)之后,我确实必须在我的第一条评论中使用该命令才能进行交叉编译。当然,一旦你安装了它,你就可以从那时起构建......
  • @ain 不,只是来自官方Downloads 页面的“裸”二进制 Go 发行版。 go 工具会重新编译从标准库(从源代码)到目标 os/arch 所需的一切,这就是为什么它需要更长的时间。
  • @ain 要添加,您可以随时运行go tool dist list 列出您安装的 Go 支持的 OS/ARCH 组合。
【解决方案2】:

我发现了一个问题并解决了它。

在我的 Windows 10 中这些命令

set GOARCH=amd64
set GOOS=linux

在 cmd 和 powershell 控制台中真的什么也没做!只有它的工作方式是我需要打开控制面板 -> 系统 -> 系统高级设置 -> 环境变量并手动添加它们。

如果您使用 Visual Studio Code 进行开发,请不要忘记重新启动它。

2017 年 2 月 24 日更新

您可以像这样在 windows powershell 中设置变量

$env:GOOS = "linux"

并将其读取到控制台

$env:GOOS

【讨论】:

  • “SET 命令实际上什么也没做!” SET 命令不会在系统范围内设置环境变量,仅在当前命令 shell 中设置。所以对其他 shell 和应用程序没有影响,这已经不是什么秘密了。
  • 但这甚至不适用于当前的命令外壳。我设置它,进行构建,将我的文件复制到我的 linux 容器,运行“文件”命令并查看该文件是为 Windows 构建的。只有当我按照我描述的方式对整个系统进行操作时,它才会起作用。我不知道为什么,但我的 windows 10 就是这样
  • 只针对vscode,可以这样做:文件->首选项->设置:搜索go.toolsEnvVars => 里面添加:"GOARCH": "amd64", "GOOS": "linux"不需要重启
【解决方案3】:

在带有 Go 1.14 的 Windows 10 上对我有用的是:

go env -w GOARCH=amd64
go env -w GOOS=linux
go build -o test-linux test.go

就是这样。

我在 Windows 命令提示符和 Windows PowerShell 中都试过了。结果没有区别。

如果您在文本编辑器中打开二进制文件,您应该会看到它以 ELF (Linux) 开头,而不是 MZ (Windows)。

我在具有给定架构的 Linux 机器 (RHEL 7.3) 上运行它,它运行正常。它给出了正确的输出。

将文件复制到 Linux 机器后,我必须使其可执行:

$ chmod +x test-linux

然后我就可以运行它了:

$ ./test-linux

您还可以在 Linux 上运行以下命令,以获取有关文件的更多详细信息:

$ file test-linux
test-linux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

当然,如果您的架构已经是amd64,那么您不必再次设置它。你可以设置GOOS。

您还可以在完成交叉编译后将GOOS 恢复为windows。当我关闭 Windows 命令提示符和 PowerShell 并运行 go env 以查看 Go 环境变量列表时,GOOS 保留了 linux 值。我没有尝试重新启动 Windows。所以,如果你现在想再次为 Windows 编译:

go env -w GOOS=windows

您需要使用正确的大小写,如此处所示。例如,Windows 或 Linux 将不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 2017-02-03
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 2021-11-20
    相关资源
    最近更新 更多