go: runtime: tracking bug for ARM-based macOS and GOOS/GOARCH values

The ARM-based Mac rumors of the past couple years continue to heat up (e.g. https://www.theverge.com/2020/3/27/21196611/arm-macbook-desktop-apple-2021-release-date)

Has anybody given any thought to what we’re going to do with runtime.GOOS and runtime.GOARCH if/when that happens, so we don’t add ambiguity between darwin/arm64 (which currently means iOS only) and darwin/arm64 (which might also mean macOS in the future)?

Changing GOARCH seems out.

Adding GOOS=macos would break any code that switches on those values.

Perhaps some magic behavior like we did for GOOS=android (implies linux build tags) and GOOS=illumos (implies solaris build tags)? But what would still break code that checks runtime.GOOS.

Perhaps keep darwin/arm64 on both iOS and macOS but add some some runtime exported const DarwinOS = {"macos", "ios", ""} that people could switch on when it matters?

If there’s new API, might be nice to get that in earlier. But OTOH, don’t want to jump the gun if rumors don’t pan out.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 48
  • Comments: 154 (72 by maintainers)

Commits related to this issue

Most upvoted comments

For those like me seeking some information on how to get go working on an Apple Silicon Mac now, here is the way I had this working for myself for the master branch.

  1. You should have access to a different architecture, preferably Apple’s Intel Mac.
  2. On that Mac you should have already a go installed, I had version 1.15.5 installed via homebrew.
  3. Download the source of golang and cd into the src folder. You should be in the master branch.
  4. Run this to build the binaries for ARM Darwin arch: GOARCH=arm64 GOOS=darwin ./bootstrap.bash.
  5. Copy the go-darwin-arm64-bootstrap.tbz to your Apple Silicon Mac, and unwrap it into /opt/go/ folder, so that the bin fodler can be in /opt/go/bin path.
  6. Add /opt/go/ to your PATH variable.
  7. Sign every binary in paths /opt/go/bin/ and /opt/go/pkg/tools/ with codesign -s - <binary_path>.

This should work now.

If darwin/arm64 doesn’t work for macos, then I think we should reclaim it for macos and move ios over to ios/arm64, much as we have android as an almost-synonym for Linux on mobile. (Many fewer GOOS=darwin users on mobile than desktop.)

I’ve thought about whether we should have GOOS=macos independently of this issue, but it seems like too much churn for too little benefit.

Interesting to note that way back when, we could have done GOOS=osx and we’d be in the same boat of having the wrong name. Moving to GOOS=macos will only match Apple terminology until the next OS rename.

I don’t believe we have to do anything in the Go 1.15 release notes. Nothing is changing for Go 1.15.

As Go 1.16 beta is released, now macOS ARM64 binary release can be downloaded at https://golang.org/dl/#go1.16beta1 .

Apple just announced in their State of the Union talk at WWDC that they’ve developed patches for Go, that they hope to submit in the coming days. So exciting! Hope we can onboard support for macOS/arm64 (even on a branch) very soon. 😃

Curious, is there any talk of an Apple Silicon darwin/arm64 backport from 1.16 to 1.15.x to get it out there before 1.16 scheduled for Feb 1st 2021…? Or an early 1.16 release?

New Apple Silicon/M1 hardware is starting to arrive in peoples hands already 😃 I can imagine a lot of projects will be waiting on a release before they push out new releases of their projects.

As far as I can tell, the darwin/arm64 port is now pretty much on parity with the darwin/amd64 port, and I don’t expect much to be done on this issue. I think we can close this.

Feel free to reopen, or open a new issue, if I missed anything.

Can we please build universal binaries (Universal 2: x86-64/arm64 bundles) from go build?

Example:

GOOS=darwin GOARCH=universal2

Use case:

I build a go binary in my new ARM Mac and distribute it to a partner with a 2018 Mac and another one with Apple silicon

@jpap Thanks for the heads up. A recording of that talk is available at https://developer.apple.com/videos/play/wwdc2020/102/. The phrase I heard around the 20:34 mark is a less definitive “we’ve already done the initial work for some of the more widely used open-source projects”, so we may need to wait to learn details.

That’s right, with the statement that followed: “…and we will be publishing patches to them in the next days”. You can see a reference to the Go project on the slide behind the speaker. Now I’ve only just noticed the bold type on some projects on the second slide below – perhaps Apple will focus on those first, for which Go may have to wait.

image

image

Also, in case it helps anyone, I’ve written a fairly rough walkthrough on compiling Go for the M1 entirely on the M1 itself: https://gist.github.com/Dids/dbe6356377e2a0b0dc8eacb0101dc3a7

The process is fairly straightforward, but after spending a few days scratching my head due to various issues (3rd party terminals running in x86 mode for example), this is the best I could come up with.

I think the suggestion here is:

  1. add ios as a valid GOOS value
  2. let ios imply darwin much as android implies linux

This will potentially break any existing mobile programs that test runtime.GOOS and expect to see darwin. After this change they will see ios.

This suggests that for 1.15 we should

  1. add ios as a valid build tag that implies darwin
  2. announce in the release notes that we plan to change to GOOS=ios in a future release

Everyone probably knows this, but for anyone who comes across this in the future, Go 1.16 was released today with non-prerelease, first-class support for darwin/arm64. https://golang.org/doc/go1.16#darwin

I don’t believe so. We do have hardware coming, though.

CLs for #42684 are in. Now it should work at tip (without checking out https://go.googlesource.com/go/refs/changes/58/272258/1 ).

It’s codsigning, the compiler started to work once I ran codesign -s - on bin/ and pkg/tool/ binaries.

I imagine the DTK might have it disabled, which sort of makes sense but sets developers up for this.

I’ll open an issue about it, since it stops “go test” and “go run” from working, and “go build” generates binaries that are not runnable.

If anyone wants to try this before we get the actual patches, I have some instructions in https://gist.github.com/tonistiigi/290d2e7118fe6f581e336bf3553b4501 .

Mostly everything seemed to work. I also built go itself, and that worked fine (and built go seemed to work fine), but when I tried to build on the native arch with GOROOT_BOOTSTRAP it errors somewhere in the middle of the build. Didn’t have time to debug what was going on there yet.

Go 1.15.x does not support macOS/ARM64 port, only tip (Go1.16-to-be) does. For the moment, you may want to use the version mentioned at https://github.com/golang/go/issues/42684#issuecomment-731821237, to incorporate some ongoing work.

I don’t think bootstrapping from Go 1.4 would work, because Go 1.4 doesn’t support darwin/arm64.

So cross-bootstrapping is the easiest option. It can be done by running GOARCH=arm64 GOOS=darwin ./bootstrap.bash in GOROOT/src with Go tip on ~any platform.

@ottob thanks for bringing this up.

The example in the video assumes mach_absolute_time returns nanoseconds, which is the problem. We don’t assume that and query the scaling factor and do the scaling ourselves. So it is not a problem.

Using clock_gettime_nsec_np would be simpler, as we don’t need to do the scaling ourselves. But when I tried it, it is actually slower (because it seems to call mach_absolute_time internally but also does more dispatching and doesn’t seem to memoize the scaling factor). I think we’ll keep the current code for now.

It would not be hard to use 2 go build commands and lipo to make your own fat binaries.

It would not be hard for the Go tool to build fat binaries for pure Go programs. cgo programs might be quite a bit trickier as we’d need to specify multiple C toolchains, one for each arch.

Example: GOOS=darwin GOARCH=universal2

Perhaps a comma separated list for the architecture could avoid having to define new GOARCH values? The “universal” (fat-binary) executable is just a set of slices, one for each architecture, which maps nicely to a comma separated list (array).

GOOS=darwin
GOARCH=amd64,arm64

We’ll cross that bridge when we come to it.

(It seems fairly unlikely that Apple would stop running existing programs. If they introduce new instructions that we care about, we can address that through a GOARM64 environment variable if necessary.)

gomobile uses ios tag and also we use the ios tag in crypto/x509 package. gomobile sets GOOS/GOARCH for crosscompile so it needs to use the right value depending on the go version. I don’t think that’s too difficult.

In addition to gomobile, cc/ @eliasnaur elias.naur@gmail.com for gio, @hajimehoshi for ebiten users

On Fri, May 1, 2020 at 2:38 PM cherrymui notifications@github.com wrote:

I think (but not sure) gomobile sets ios tag, to distinguish iOS emulator on x86 vs. macOS.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/38485#issuecomment-622509793, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGESL63JC4FILQFUNGUQH3RPMJJPANCNFSM4MJZNOPQ .

– __

@makeworld-the-better-one Go 1.15.x does not support macOS/ARM64 port (see https://github.com/golang/go/issues/38485#issuecomment-735940523). Use tip of the master branch.

Please see the open issues for the status of the darwin/arm64 port (especially #42684 and #42700).

You can use a Go 1.15 binary release under Rosetta 2 and bootstrap.sh (or even GOARCH=arm64 ./make.bash) to generate a darwin/arm64 toolchain directly on an M1 machine. Please ask on the golang-nuts mailing list if you need help with it.

Sorry for my direct jump in.

  • What’s the current status of installing Go on darwin/arm64? The issue was closed, but it seems still a few problems out there.
  • Will Go 1.4 adding bootstrap support for darwin/arm64? How will we compile/install Go without having another well-supported machine before Go 1.16 release?

https://github.com/golang/go/issues/38485#issuecomment-730247329 Would it be possible to run these steps (cross compile?) from Linux amd64 instead of Apple Intel? I’m getting the following errors:

$ GOARCH=arm64 GOOS=darwin ./bootstrap.bash
#### Copying to ../../go-darwin-arm64-bootstrap

#### Cleaning ../../go-darwin-arm64-bootstrap

#### Building ../../go-darwin-arm64-bootstrap

Building Go cmd/dist using /home/ec2-user/go. (go1.15.5 linux/amd64)
Building Go toolchain1 using /home/ec2-user/go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
Building Go toolchain3 using go_bootstrap and Go toolchain2.
Building packages and commands for host, linux/amd64.
Building packages and commands for target, darwin/arm64.
# cmd/addr2line
/home/ec2-user/go-darwin-arm64-bootstrap/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/tmp/go-link-434896474/go.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status

# cmd/api
/home/ec2-user/go-darwin-arm64-bootstrap/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/tmp/go-link-513009092/go.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status

@MarkusBansky I have indeed signed them, but also found a much better/“official” fix here: https://github.com/golang/go/issues/42684#issuecomment-731821237

This patch/commit fixes the actual issue and means we no longer need to sign anything ourselves, as apparently the LLVM linker automatically signs binaries/libraries when linking. Much more on this topic in the issue I linked.

But do note that I’ve yet to get the runtime to compile, as it seems to just stall endlessly when compiling (bootstrap toolchain compiled fine on both Intel and M1). Left it compiling for a few hours on the M1, but it still wasn’t done, so gave up for the day.

Oops, looks like #42684 covers the codesigning issue now.

I just tried bootstrap.bash and it worked as well. Maybe the DTK and the machines on the market behave differently? That would be weird…

1.16 is scheduled for Feb 1. I fixed the milestone due date.

Simulators and tvOS have not been really “supported” platforms. They mostly “work” in practice, but we haven’t really thought about them. If we want to actually “support” them, I think we need to think them more holistically (in #42477 or a separate issue). @eliasnaur can probably chime in. Thanks.

Is ios/amd64 for the iOS emulator going to part of Go 1.16? The freeze is near, and I don’t think darwin/amd64,tags=ios is the right configuration for the emulator.

@bcmills actually I’m about to mail a CL for that, good timing 😃 I tried it a while ago and there were some tests failing. I have been fixing them along the way, and understanding the ones that actually need to be skipped. As of last night I think I got them all.

@eliasnaur , could you share more information about GOOS=ios on AMD64? Specifically, how does it differ from GOOS=darwin? (Is it just all places that are currently tagged with “ios”? Is that all?) Also, asides from the builder, how do we know if it “works” (even on our local machine)? Is it that GOOS=ios GOARCH=amd64 all.bash passes on an AMD64 macOS machine, or something else? Thanks!

the gomobile tool already sets an “ios” build constraint whenever targeting iOS (see code here, here and here). That means we don’t need to make changes in Go 1.15 for people to be able to start moving iOS-specific code behind a potentially more future-proof ios build constraint.

I just want to mention that gomobile is not the only way to build Go programs on iOS. There are probably other tools (not sure if they have ios tag set). Also it could be done by hand (only using Go tools).

(I’m not suggesting we should or should not do anything for it in Go 1.15.)

As far as I know about mobile application developing, there should be no problem to add ios to GOOS 😃

I think (but not sure) gomobile sets ios tag, to distinguish iOS emulator on x86 vs. macOS.