Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: should not require -arch flag for cross compiling to Darwin with cgo #59544

Closed
scott-cotton opened this issue Apr 11, 2023 · 3 comments
Closed
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@scott-cotton
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.20.3 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ubuntu/.cache/go-build"
GOENV="/home/ubuntu/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/ubuntu/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/ubuntu/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/ubuntu/tmp/repro/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3333528793=/tmp/go-build -gno-record-gcc-switches"

What did you do?

here is a repro:

package main

import "fmt"

/*
int number() {
    return 20;
}
*/
import "C"

func main() {
	fmt.Printf("%d\n", C.number())
}

Then on any run of the mill linux run

ubuntu@ip-172-31-33-216:~/tmp/repro$ CGO_ENABLED=1 GOOS=darwin go build .
# runtime/cgo
gcc: error: unrecognized command-line option '-arch'

What did you expect to see?

The program compile without error

What did you see instead?

see above. It seems to me the commit https://go-review.googlesource.com/c/go/+/283812 caused this, and that the flag -arch should be added when runtime.GOOS is Darwin, not when the env var GOOS is Darwin. I also tried installing clang on linux to get around this, thinking it was clang that accepted -arch, but that flag appears to be specific to Darwin.

@scott-cotton scott-cotton changed the title affected/package: cgo cross compilation cgo cross compilation to Darwin from linux fails Apr 11, 2023
@bcmills
Copy link
Member

bcmills commented Apr 11, 2023

A stock Linux C toolchain typically cannot compile for macOS. (For one, it lacks the C headers for macOS system libraries.)

Can you cross-compile a pure C binary for macOS using your compiler? That's certainly a minimum requirement for being able to cross-compile a cgo program.

@bcmills bcmills added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Apr 11, 2023
@scott-cotton
Copy link
Author

A stock Linux C toolchain typically cannot compile for macOS. (For one, it lacks the C headers for macOS system libraries.)

Can you cross-compile a pure C binary for macOS using your compiler? That's certainly a minimum requirement for being able to cross-compile a cgo program.

I think I was confused by the error and PR adding the -arch flag. The reasoning for the PR linked above is that, on Darwin with the system clang based compiler, one requires this flag. However, it is quite a leap to go from that to enforcing that the cross compiler have this flag as well. For example, one may need to wrap $CC to discard the argument or use something like -Wno-unused-command-line-argument

To follow up to the question of actually cross compiling linux->Darwin, I've found that

  1. yes I can compile with clang and an appropriate -platform flag, but more cross compile infra is needed for linking. If I compile on linux and link on Darwin it runs but the code doesn't look really well-targeted to me (clang translates apple to iphoneos or some such somewhere in the tool chain).
  2. the existing mechanisms for cross compiling such as https://ostatic.com/darwin-arm and https://github.com/tpoechtrager/osxcross are quite heavy weight, enough for me to consider just building on different machines or backward engineering things to sys call level and using pure Go.

However, on my end it still seems that -arch should be added conditionally based on $HOSTOS/runtime.GOOS rather than based on $GOOS, since injecting flags based on $GOOS may well not be appropriate for a cross compiler.

@scott-cotton scott-cotton changed the title cgo cross compilation to Darwin from linux fails cgo cross compilation to darwin from linux confusing error message. Apr 13, 2023
@seankhliao seankhliao changed the title cgo cross compilation to darwin from linux confusing error message. cmd/compile: should not requir Jul 9, 2023
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 9, 2023
@seankhliao seankhliao changed the title cmd/compile: should not requir cmd/compile: should not require -arch flag for cross compiling to Darwin with cgo Jul 9, 2023
@seankhliao seankhliao added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. and removed WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels Jul 9, 2023
@mknyszek mknyszek changed the title cmd/compile: should not require -arch flag for cross compiling to Darwin with cgo cmd/go: should not require -arch flag for cross compiling to Darwin with cgo Jul 12, 2023
@mknyszek mknyszek added this to the Backlog milestone Jul 12, 2023
@cherrymui
Copy link
Member

There are ARM64-based macOS and x86-64 based macOS. Without passing -arch it is unclear which one you're targeting. Especially on an ARM64-based macOS machine with Rosetta 2 emulation, the default arch choice can be quite confusing and is often not what user whats. So we pass -arch explicitly to make that clear.

From the comment above it sounds like you're not using either of the C cross toolchains. Then what do you use? Without a proper C cross toolchain, cross compiling for cgo would not work even if we don't pass -arch.

I don't think we're going to change this behavior, at least for now. If you want to use a specific C cross toolchain that works well except -arch, we can see what the best we can do from there. Thanks.

@cherrymui cherrymui closed this as not planned Won't fix, can't repro, duplicate, stale Jul 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants