如何在M1上编译带有CGO的Go项目

mb5ffbc8bbd6412 · · 2498 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


之前一直用的公司17年的本子,卡的是在不行。最近入m1 13 inch/16g, 在使用上一直存在一些问题,包括 Chrome 的arm版本也不例外,存在各种卡死的现象。经过Rosetta 2 转译过的代码有明显的卡顿感。

最典型的例子就是在goland 中如果使用了非 go1.16-darwin/arm64 版本的go,在写代码的时候不全提示,代码搜索都略卡。但是如果使用了 go1.16 又会导致一些使用了 CGO 的项目无法编译,相信很多小伙伴也遇到了相同的问题。

BTW, 由于是吃螃蟹,对于这些软件也有些心理预期,m1也有些好的方面比如电池,散热控制是真的 nice.

简述

在使用 go1.16 时主要是一些 CGO 编译问题,错误示例如下:

/usr/local/go/pkg/tool/darwin_arm64/link: running clang failed: exit status 1
ld: warning: ignoring file /var/folders/gg/fgcf1wps4tz51d_x38ybzpv00000gn/T/go-link-948954574/go.o, building for macOS-x86_64 but attempting to link with file built for unknown-arm64
...
Undefined symbols for architecture x86_64:  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)复制代码

看提示主要是由于 clang/clang++ 的架构不对, 使用clang --version 可以查看到使用的 llvm 是 x86 架构的。

LLVM

这里引用一下维基百科的相关词条做一下简单介绍,clang/clang++ 只是包含在LLVM中的工具。

LLVM是一套编译器基础设施项目,为自由软件,以C++写成,包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端。它是为了任意一种编程语言而写成的程序,利用虚拟技术创造出编译时期、链接时期、运行时期以及“闲置时期”的优化。

然后通过 homebrew 再次安装了 llvm, 再次查看版本还是 x86的。难道LLVM 没有 drawin/arm64的么。带着好奇心我去 了 homebrew 网站一探究竟. 然后看到了,是有arm的llvm版本的,但是 brew 还是 安装了x86 版本的 llvm.

于是便尝试安装了 arm64 的 homebrew.

Homebrew arm64 版本安装

将 homebrew 安装在 opt目录下

# 创建文件夹sudo mkdir /opt/homebrew && cd /opt/homebrew# 变更权限为当前用户sudo chown -R $(whoami) /opt/homebrew# 执行安装curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew复制代码

然后将 /opt/homebrew/bin 写入你的 ~/.zshrc 即可, 当然你要是懒也可以使用绝对路径来用。

echo "PATH=/opt/homebrew/bin:$PATH" >> ~/.zshrc # 千万别少 '>' [doge]复制代码

通过下面命令可以看到brew 的配置信息

brew config复制代码

输入如下:

HOMEBREW_VERSION: 2.7.5
ORIGIN: https://github.com/Homebrew/brew
HEAD: bca4804a9e48de5319383d3eddadaa7f054c77da
Last commit: 24 hours ago
....
Homebrew Ruby: 2.6.3 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
CPU: octa-core 64-bit westmere
Clang: 12.0 build 1200
Git: 2.24.3 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 7.64.1 => /usr/bin/curl
Java: 12.0.1, 1.8.211.12, 1.8.0_211
macOS: 11.1-x86_64
CLT: 12.3.0.0.1.1607026830
Xcode: N/A
XQuartz: 2.7.11 => /opt/X11
Rosetta 2: true复制代码

可以看到  macOS 的配置是x86的,但是可以通过在 brew 前加 arch -arm64 来变更配置.

arch -arm64 brew config复制代码

LLVM arm64 版本安装

安装好 arm64版的 brew后 可以使用以下命令安装llvm了, 默认是最新的11.

arch=arm64 /opt/homebrew/bin/brew install llvm复制代码

过程中我们可以看到下载的包是 arm64 的版本。 安装完成后可以通过以下命令来查看 clang 版本

clang --version复制代码

Build 验证

安装完成后, 使用 go1.16 编译带有 CGO 的项目进行验证, 久违的 build pass 让人顿感热泪盈眶 ????

不得不吹的是,编译速度是真的快!


有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:mb5ffbc8bbd6412

查看原文:如何在M1上编译带有CGO的Go项目

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2498 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传