如何编译在 M1 (arm64) 上使用 C 的 amd64 二进制文件 Mac

How to compile an amd64 binary that uses C on an M1 (arm64) Mac

GOARCH 设置为 arm64(或被省略)时,我的应用程序可以正常编译。但是,当我尝试编译 amd64 二进制文件 (GOOS=darwin GOARCH=amd64 go build) 时,出现以下错误:

package [mainPackage]
        imports [internalPackageThatUsesC]: build constraints exclude all Go files in [pathToInternalPackageThatUsesC]

[internalPackageThatUsesC] 由 3 个文件组成——一个包含实现的 Objective C 文件、一个头文件和一个为本机代码提供接口的 Go 文件。以下是 Go 文件:

// +build darwin

package [internalPackageThatUsesC]

/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Cocoa

#include <Cocoa/Cocoa.h>
#include "[headerFile].h"
*/
import "C"
import (
    "encoding/json"
    "sync"
    "unsafe"
)

... public functions that use the C library to interact with the native code

带有 [] 注释的名称表示它们是实际名称的占位符。

我尝试 运行 它与 arch -x86_64 但输出是相同的。

这里有什么问题?我需要添加另一个构建标签吗?

P.S。我在 Whosebug 上发现了关于此错误的问题,但其中 none 是关于针对 amd64 进行编译的。 问题最接近,但它是特定于 WebAssembly 的。

以下是go env的结果:

GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/fperson/Library/Caches/go-build"
GOENV="/Users/fperson/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/fperson/.asdf/installs/golang/1.16.4/packages/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/fperson/.asdf/installs/golang/1.16.4/packages"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/fperson/.asdf/installs/golang/1.16.4/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/fperson/.asdf/installs/golang/1.16.4/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.16.4"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/fperson/workspace/personal_projects/timeow/timeow-mac/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/mh/02gmkb756x15018g919jcg980000gn/T/go-build4031963624=/tmp/go-build -gno-record-gcc-switches -fno-common"

(as you posted) talks about cgo. cgo invokes platform compiler with platform specific headers/libs (on Mac, with framework too). When you cross-compile with CC, you also need cross-compile compiler + headers/libs + frameworks. It is not easy: you may need tools like xgo。但是仍然交叉编译可能会失败。

Go 不一样,Go 在每个 OS/arch 上重新实现了一个 go 或 plan9 ASM 中的 HAL。因此,当您在 arm64 上同时交叉编译 cgo + go for am64 时,go build 将尝试将“cgo+arm64”与“go+amd64”混合。遗憾的是,它是内置 go build 工具的空集。

参考@fperson的.

在我的例子中,我还需要将 CGO_ENABLED 设置为 true。该应用程序现在可以使用 GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build

为 amd64 正常编译

(感谢回答)