简体   繁体   English

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

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

My app compiles fine when GOARCH is set to arm64 (or is omitted).GOARCH设置为arm64 (或被省略)时,我的应用程序编译良好。 However, when I try to compile an amd64 binary ( GOOS=darwin GOARCH=amd64 go build ), I get the following error:但是,当我尝试编译 amd64 二进制文件( GOOS=darwin GOARCH=amd64 go build )时,出现以下错误:

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

[internalPackageThatUsesC] consists of 3 files – an Objective C file with the implementation, a header for it and a Go file which provides an interface for the native code. [internalPackageThatUsesC]由 3 个文件组成——一个带有实现的目标 C 文件,一个 header 和一个 Go 文件,它提供原生代码的接口。 Following is the Go file:以下是 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

Names annotated with [] mean they are a placeholder for the actual name.带有[]注释的名称表示它们是实际名称的占位符。

I tried to run it with arch -x86_64 but the output is the same.我尝试使用arch -x86_64运行它,但 output 是相同的。

What's the problem here?这里有什么问题? Do I need to add another build tag?我需要添加另一个构建标签吗?

PS I found questions on StackOverflow about this error but none of them were about compiling for amd64. PS 我在 StackOverflow 上发现了关于这个错误的问题,但没有一个是关于为 amd64 编译的。 This question was the closest but it was WebAssembly-specific. 这个问题是最接近的,但它是特定于 WebAssembly 的。

Following is the result of go env :以下是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"

The answer to the wasm question (as you posted) talks about cgo. wasm 问题的答案(正如您发布的那样)谈到了 cgo。 cgo invokes platform compiler with platform specific headers/libs (on Mac, with framework too). cgo 使用平台特定的头文件/库调用平台编译器(在 Mac 上,也带有框架)。 When you cross-compile with CC , you also need cross-compile compiler + headers/libs + frameworks.当您使用CC进行交叉编译时,您还需要交叉编译编译器 + 头文件/库 + 框架。 It is not easy: you may need tools like xgo .这并不容易:您可能需要像xgo这样的工具。 But still cross-compile may fail.但仍然交叉编译可能会失败。

Go is different, Go re-implements a HAL in go or plan9 ASM on each OS/arch. Go 不同,Go 在每个 OS/arch 上的 go 或 plan9 ASM 中重新实现了 HAL。 So when you cross-compile cgo + go for am64 on arm64 together, go build will try to blend "cgo+arm64" with "go+amd64".因此,当您在 arm64 上为 am64 交叉编译 cgo + go 时, go build将尝试将“cgo+arm64”与“go+amd64”混合。 Sadly, it is an empty set for the built-in go build tool.遗憾的是,内置的go build工具是一个空集。

In my case, I also needed to set CGO_ENABLED to true.就我而言,我还需要将CGO_ENABLED设置为 true。 The app now compiles fine for amd64 with GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build该应用程序现在可以使用GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build为 amd64 正常编译

(Thanks to this answer) (感谢这个答案)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 cgo 从 linux/amd64 交叉编译到 darwin/arm64? - How to cross-compile from linux/amd64 to darwin/arm64 with cgo? 无法在 Vscode M1 Mac (arm64) 上调试 Golang - Unable to debug Golang on Vscode M1 Mac (arm64) CGO:使用 cgo_enabled = 1 从 mac/windows 交叉编译到 linux amd64 - CGO: Cross compile from mac/windows to linux amd64 with cgo_enabled = 1 Go1.18:不支持使用 go 版本 go1.18 darwin/amd64 编译的调试程序。 将 go sdk 用于 darwin/arm64 - Go1.18: Debugging programs compiled with go version go1.18 darwin/amd64 is not supported. Use go sdk for darwin/arm64 在amd64上拆分堆栈是不必要的 - Split stacks unneccesary on amd64 从Ubuntu amd64到arm7l进行交叉编译:exec用户进程导致“ exec格式错误” - Go Cross Compilation from Ubuntu amd64 to arm7l : exec user process caused “exec format error” 如何使用 golang docker 容器构建 linux/amd64 golang 可执行文件? - How to build linux/amd64 golang executable with golang docker container? 交叉编译:“用户:目前未在linux / amd64上实现” - Cross compiling: “user: Current not implemented on linux/amd64” “用户:当前未在linux / amd64上实现”在fedora上带有新鲜的golang - “user: Current not implemented on linux/amd64” with fresh golang on fedora 连接到 mongodb 容器版本 6.0.2 时出错 | amd64/蒙戈 - Error connecting to mongodb container version 6.0.2 | amd64/mongo
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM