在Mac上从源码编译Go1.16时遇到Symbol not found: _clock_getime错误
在Mac上从源码编译Go1.16时遇到Symbol not found: _clock_getime错误 大家好 - 这是我第一次在论坛发帖。我使用Go语言编程已有几年,曾在Macbook、戴尔Windows电脑,甚至树莓派3和4上开发。最近似乎是我的Mac让我遇到了问题。
我最近在我的MacbookPro5,5上全新安装了MacOS 10.11.6(El Capitan)。由于Home Brew不再支持10.11.6,我决定尝试从源代码编译Go。我顺利下载并安装了Go1.14.6。然后下载了Go1.16的源代码压缩包。 当我运行./all.bash时,得到了以下输出:
BJD:src brent$ ./all.bash
Building Go cmd/dist using /usr/local/go. (go1.14.15 darwin/amd64)
Building Go toolchain1 using /usr/local/go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
Building Go toolchain2 using go_bootstrap and Go toolchain1.
dyld: Symbol not found: _clock_gettime
Referenced from: /Users/brent/go/pkg/tool/darwin_amd64/go_bootstrap
Expected in: flat namespace
go tool dist: FAILED: /Users/brent/go/pkg/tool/darwin_amd64/go_bootstrap install -gcflags=all= -ldflags=all= -i cmd/asm cmd/cgo cmd/compile cmd/link: signal: trace/BPT trap
我的Go环境变量是:
BJD:src brent$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/brent/Library/Caches/go-build"
GOENV="/Users/brent/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/brent/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/brent/go/src/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 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/p_/kcmsl1yx7xv5xmwmgm7fmrmm0000gn/T/go-build855851525=/tmp/go-build -gno-record-gcc-switches -fno-common"
我该如何解决这个问题?
我不确定为什么会发生这种情况。使用 Go1.14.15 来编译 Go1.16,它却告诉我仍然依赖某些操作系统库?我不明白。为什么它不是自包含的?我没有发现任何 Go 代码依赖问题。
感谢您提供的关于 runtime/sys_darwin_amd64.s 的线索。
Go 不需要链接到共享库,但它需要一个操作系统。根据 Go 的发布说明,Go 1.14 是最后一个支持 El Capitan 的版本。此后的 Go 版本需要 macOS 提供的功能,而这些功能在 El Capitan 中不存在。
这个问题是由于macOS 10.11.6缺少clock_gettime系统调用导致的。Go 1.16需要这个系统调用,但macOS 10.11.6没有提供。以下是解决方案:
解决方案1:使用Go 1.15或更早版本 由于macOS 10.11.6的限制,建议使用Go 1.15.x版本:
# 下载Go 1.15.8(最后一个支持macOS 10.11的版本)
wget https://dl.google.com/go/go1.15.8.darwin-amd64.tar.gz
# 解压并安装
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.15.8.darwin-amd64.tar.gz
解决方案2:修改Go源码以兼容旧版macOS
如果你必须使用Go 1.16,可以修改源码来避免使用clock_gettime:
- 编辑
src/runtime/os_darwin.go文件:
// 在文件顶部添加以下代码
//go:build !ios
// +build !ios
// 找到clock_gettime相关代码,替换为:
func nanotime() int64 {
var ts timespec
if clock_gettime(CLOCK_MONOTONIC, &ts) != 0 {
// 回退到旧的gettimeofday方法
var tv timeval
gettimeofday(&tv, nil)
return int64(tv.tv_sec)*1e9 + int64(tv.tv_usec)*1e3
}
return int64(ts.tv_sec)*1e9 + int64(ts.tv_nsec)
}
- 编辑
src/runtime/sys_darwin_amd64.s汇编文件,确保使用兼容的系统调用。
解决方案3:使用交叉编译 在另一台支持Go 1.16的机器上编译,然后复制到macOS 10.11.6:
# 在支持的系统上编译Go 1.16
GOOS=darwin GOARCH=amd64 ./bootstrap.bash
# 将编译好的工具链复制到macOS 10.11.6
解决方案4:升级macOS
考虑升级到macOS 10.12或更高版本,这些版本原生支持clock_gettime系统调用。
验证安装:
# 检查Go版本
go version
# 测试简单程序
cat > test.go << 'EOF'
package main
import "fmt"
func main() {
fmt.Println("Go is working!")
}
EOF
go run test.go
对于macOS 10.11.6,推荐使用解决方案1安装Go 1.15.8,这是最后一个完全支持该系统的稳定版本。

