英文:
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_IP
和syscall.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 ofsyscall.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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论