Go有自己的assembler和linker, 能够自己从源代码一直做到最后机器码。再加上整个toolchain都是用Go实现的可以到处移植,所以任何可以运行Go compiler的host machine都能输出所有支持的架构的binary. 没有准备特殊toolchain做交叉编译的需要。

Assembler设计时就考虑到支持多架构,让不同架构的汇编源码格式相同,然后用简单的码表就能输出不同架构的机器码。这其实就是Rob Pike在Gophercon 2016上的演讲题目 https://talks.golang.org/2016/asm.slide ,看视频评论似乎大部分人都没听懂或者把它跟LLVM的中间码混淆了。

至于不同OS的支持,一是可执行文件的格式不同,这是linker最后一点小工作。 二是系统API, Go标准库是self-contained的,甚至不依赖glibc, 大部分时候只需要实现特定系统的syscall和特有功能就可以了,这部分实现通常涉及汇编代码,而Go的assembler又是跨平台的,于是事情就很简单了。