有没有办法在Apple Silicon M上运行amd64/linux虚拟机?

huangapple go评论75阅读模式
英文:

Is there any way to run an amd64/linux VM on Apple Silicon M?

问题

我正在使用Go编写一个关于透明代理的程序,但是syscall.SetsockoptInt(int(s), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1)只支持amd64/linux(其他版本没有常量syscall.SOL_IPsyscall.IP_TRANSPARENT)。

所以,即使我在M1上运行一个并行的VM(arm64/linux),我仍然无法成功构建我的程序。有没有办法解决这个问题?

英文:

I'm writing a program about transparent proxy with Go, but syscall.SetsockoptInt(int(s), syscall.SOL_IP, syscall.IP_TRANSPARENT, 1)is only supported on amd64/linux (Other versions don't have constant syscall.SOL_IP and syscall.IP_TRANSPARENT).

So even if I run a parallel VM (arm64/linux) on M1, I still could not build my program successfully. Is there any way to solve it?

答案1

得分: 0

我不确定问题的本质是什么。IP_TRANSPARENT 是特定于 Linux(一个操作系统内核)的,因此任何使用它的代码都必须在 Linux 上运行。调试(运行中的进程)也必须在 Linux 上进行,希望这一点现在很明显。

但这并不影响构建过程:在 Linux 上构建时,如果你的 Go 版本在其 syscall 包中定义了 IP_TRANSPARENT,那么应该可以工作。

这意味着:

  • 在具有 Linux 客户机的虚拟机上运行为 linux/amd64 构建的程序并使用 syscall.IP_TRANSPARENT 应该可以工作。
  • 在具有 Linux 客户机的虚拟机上从源代码构建该程序应该可以工作。

但是,在非本机平台上进行“普通”构建(在我们的情况下是 darwin/arm64)将无法工作,这可能是你困惑的原因。
基本上,当你在 darwin/arm64 上构建源代码时,编译器会定位、读取和解释所有源代码,期望生成适合所在平台的可执行映像文件;syscall 包非常依赖于操作系统,可以认为它对不同的 GOOS/GOARCH 组合是不同的。
它在 darwin/arm64 上的“版本”简单地不能包含符号 IP_TRANSPARENT,因为 darwin 内核不“知道”它。

因此,如果你的问题仅仅是在 darwin/arm64 上构建 for linux/amd64,答案是交叉编译
在 Go 中,可以通过使工具链看到 GOOS 和/或 GOARCH 环境变量的显式设置来实现,这些设置与默认设置不同。
在你的情况下,你可以执行以下操作:

$ GOOS=linux GOARCH=amd64 go build

它将生成一个适用于 linux/amd64 的可执行映像文件,并且在处理源代码时,编译器将使用目标平台的定义,而不是运行的平台的定义。

然后,你可以将生成的可执行映像文件复制到客户机的文件系统中并在那里运行它,它应该可以正常工作。

你可以通过执行以下操作将这些更改“永久”应用于当前的终端会话:

$ export GOOS=linux
$ export GOARCH=amd64

TL;DR

  • 要为非本机平台进行构建,请使用交叉编译;你不需要任何类型的虚拟机。
  • 或者你可以进行“本机”构建,但是你需要将 go 安装到在虚拟机上运行的客户机中,并在那里提供项目的源代码。
  • 要运行非本机系统的可执行文件,你必须使用虚拟机(或某种模拟器)。
英文:

I'm not sure what's the essense of the question. IP_TRANSPARENT is specific to Linux (an OS kernel), so any code which makes use of it must run on Linux. Debugging (a running process) also must happen on Linux—for, I hope, reasons now obvious.

But that does not affect building: when building on Linux, that should work if your version of Go has IP_TRANSPARENT defined in its syscall package.

This means:

  • Running the program built for linux/amd64 making use of syscall.IP_TRANSPARENT on the VM with a Linux guest should work.
  • Building that program from the source code on the VM with a Linux guest should work.

But "plain" building on a non-native platform (which is darwin/arm64 in our case, if I understand correctly) will not work, and this might be the source of your confusion.
Basically, when you're building the source code on darwin/arm64, the compiler locates, reads and interprets all the sources expecting to produce an executable image file suitable for the platform it's working on; the syscall package, being highly OS-dependent, can be though of as being different for different GOOS/GOARCH combos.
Its "version" for darwin/arm64 simply cannot contain the symbol IP_TRANSPARENT because the darwin kernel does not "know" about it.

So, if your issue is merely building for linux/amd64 while working on darwin/arm64, the answer is cross-compilation.
With Go, it's done by making the toolchain see explicit settings for the GOOS and/or GOARCH environment variables—different from the assumed defaults.
In your case you could just do

$ GOOS=linux GOARCH=amd64 go build

and it will produce an executable image file ready for linux/amd64, and when processing the source code, the compiler will use the definitions for the target platform, not the platform it's running on.

You can then copy (or make availabe by other means) the produced executable image file to the guest's filesystem and run it there—it should work just fine.

You can make such changes "permanent" for the current Termial session by doing

$ export GOOS=linux
$ export GOARCH=amd64

TL;DR

  • To build for a non-native platform, use cross-compiling; you do not need any sort of VM.
  • Or you can build "natively" but then you need to install go into the guest running on a VM, and make the project's source code available there.
  • To run an executable for a non-native system you must use a VM (or some sort of emulator).

huangapple
  • 本文由 发表于 2021年8月11日 17:54:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/68739761.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定