Golang运行clang失败问题排查
Golang运行clang失败问题排查
/Users/zuvakin/.go/go/pkg/tool/darwin_amd64/link: running clang failed: exit status 1
duplicate symbol _FetchPEMRootsCTX509_MountainLion in:
/var/folders/y5/qgmddvt13_j31wl9rxtnsyj40000gn/T/go-link-718037935/000018.o
/var/folders/y5/qgmddvt13_j31wl9rxtnsyj40000gn/T/go-link-718037935/000027.o
duplicate symbol _FetchPEMRootsCTX509 in:
/var/folders/y5/qgmddvt13_j31wl9rxtnsyj40000gn/T/go-link-718037935/000018.o
/var/folders/y5/qgmddvt13_j31wl9rxtnsyj40000gn/T/go-link-718037935/000027.o
duplicate symbol _useOldCodeCTX509 in:
/var/folders/y5/qgmddvt13_j31wl9rxtnsyj40000gn/T/go-link-718037935/000018.o
/var/folders/y5/qgmddvt13_j31wl9rxtnsyj40000gn/T/go-link-718037935/000027.o
ld: 3 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
有人遇到过这种情况吗?如何解决?
相关信息: 操作系统:macOS Mojave 10.14.5 Go版本:1.12.5
更多关于Golang运行clang失败问题排查的实战教程也可以访问 https://www.itying.com/category-94-b0.html
在 macOS 上编译 Go(实际上是运行 go test)
更多关于Golang运行clang失败问题排查的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我解决了这个问题:只需要添加 CGO_ENABLED=0 就可以了。如果使用 Goland 进行构建或运行,需要在 Goland 设置中进行配置。
这个错误是由于链接器在编译过程中检测到重复的符号定义导致的。具体来说,_FetchPEMRootsCTX509_MountainLion、_FetchPEMRootsCTX509 和 _useOldCodeCTX509 这些符号在多个目标文件(000018.o 和 000027.o)中被重复定义。
问题原因分析
在Go项目中,这种情况通常发生在以下场景:
- 同一个C代码文件被多个包重复导入
- 使用了包含重复符号定义的C静态库
- 在cgo中重复声明了相同的C函数
解决方案
1. 检查依赖包中的重复C代码
首先检查你的项目是否导入了多个包含相同C代码的包。特别是检查与证书操作相关的包:
package main
/*
// 检查是否有重复的C函数定义
#include <stdlib.h>
// 确保这些函数只在一个地方定义
// 如果其他包也有相同定义,会导致链接错误
*/
import "C"
import (
"crypto/x509"
_ "your/package/with/cgo"
_ "another/package/with/similar/cgo"
)
2. 使用构建标签隔离C代码
如果确实需要在不同包中使用相同的C函数,可以使用构建标签来隔离:
// +build !other_package
package mypackage
/*
#include "my_cert_functions.c"
*/
import "C"
func MyFunction() {
// 使用C函数
}
3. 检查cgo导入的重复性
检查项目中是否有重复的cgo导入模式:
// 错误示例 - 可能导致重复符号
/*
#include "cert_utils.h"
#include "cert_functions.c" // 避免直接包含.c文件
*/
import "C"
// 正确做法 - 只包含头文件
/*
#include "cert_utils.h"
*/
import "C"
4. 清理并重新构建
执行完整的清理和重新构建:
go clean -cache
go clean -testcache
rm -rf /var/folders/y5/qgmddvt13_j31wl9rxtnsyj40000gn/T/go-link-*
go build -a
5. 检查特定包的版本冲突
这个错误常见于与macOS证书相关的包。检查是否同时导入了多个提供类似功能的包:
import (
// 检查这些包是否冲突
_ "github.com/example/certificate-manager"
_ "github.com/another/ssl-package"
)
6. 使用链接器标志
尝试使用链接器标志来忽略重复符号:
go build -ldflags="-w"
或者针对macOS特定问题:
CGO_ENABLED=1 go build -ldflags="-s -w"
实际排查步骤
- 首先运行
go mod graph检查依赖关系 - 使用
go build -x查看详细的构建过程 - 检查所有导入的包中是否包含cgo代码:
go list -f '{{.ImportPath}} {{.CgoFiles}}' ./...
这个错误通常通过识别并移除重复的C代码依赖来解决。检查你的go.mod文件中是否有版本冲突的依赖包,特别是那些提供TLS/SSL证书功能的包。

