【问题标题】:How to compile an amd64 binary that uses C on an M1 (arm64) Mac如何在 M1 (arm64) Mac 上编译使用 C 的 amd64 二进制文件
【发布时间】:2022-01-25 16:12:06
【问题描述】:

当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 运行它,但输出相同。

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

附:我在 StackOverflow 上发现了关于这个错误的问题,但没有一个是关于为 amd64 编译的。 This 问题是最接近的,但它是特定于 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"

【问题讨论】:

    标签: go go-build


    【解决方案1】:

    就我而言,我还需要将CGO_ENABLED 设置为true。该应用现在可以使用 GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build 为 amd64 正常编译

    (感谢this的回答)

    【讨论】:

    • 恭喜!我将更新我的答案以指向您的答案。
    【解决方案2】:

    The answer to the wasm question(正如您所发布的)谈论 cgo。 cgo 使用平台特定的头文件/库调用平台编译器(在 Mac 上,也带有框架)。当你使用CC进行交叉编译时,你还需要交叉编译编译器+头文件/库+框架。这并不容易:您可能需要像xgo 这样的工具。但仍然交叉编译可能会失败。

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

    参考@fperson 的own answer。

    【讨论】:

    • 有道理,谢谢!我会尝试使用xgo
    • 哦,我只能用CGO_ENABLED=1 编译它! ?
    猜你喜欢
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    • 2010-12-05
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    相关资源
    最近更新 更多