Golang 1.12.5版本中关于`-coverpkg`的问题#30374仍然存在
Golang 1.12.5版本中关于-coverpkg的问题#30374仍然存在
我遇到了与 https://github.com/golang/go/issues/30374 中报告相同的错误,该问题本应在 1.12.5 版本中修复~~,但无法在那里评论~~当然我可以评论,现在已经评论了,所以这个帖子已过时 - 抱歉造成干扰。
$ go version
go version go1.12.5 linux/amd64
`go env` 输出
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/simon/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/media/ext4_data/Coding/go"
GOPROXY=""
GORACE=""
GOROOT="/media/ext4_data/Linux/source/go"
GOTMPDIR=""
GOTOOLDIR="/media/ext4_data/Linux/source/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/simon/tmp/syncthing/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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build248314634=/tmp/go-build -gno-record-gcc-switches"
使用 -coverpkg 对所有包运行所有测试
git clone https://github.com/syncthing/syncthing.git
cd syncthing
go test -short -coverprofile coverage.out -coverpkg ./cmd/...,./lib/... ./cmd/... ./lib/...
结果出现与之前报告相同的错误:
2019/05/15 16:02:50 duplicate symbol go.constinfo.main (types 45 and 45) in github.com/syncthing/syncthing/cmd/strelaypoolsrv and /home/simon/.cache/go-build/87/87afda35dba0b8de44e2f9d449eda7ce4caef7ed781612883b4e457eab1ee3d5-d(_go_.o)
仅使用 ./... 也会出现相同问题。我彻底清理了 ~/.cache/go-build,但没有任何改变。
更多关于Golang 1.12.5版本中关于`-coverpkg`的问题#30374仍然存在的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang 1.12.5版本中关于`-coverpkg`的问题#30374仍然存在的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go 1.12.5版本中,-coverpkg标志确实存在重复符号的问题,这是由编译器在代码覆盖率检测时处理包依赖关系的方式导致的。当多个包共享相同的常量或函数时,覆盖率检测可能会生成重复的符号定义。
以下是重现该问题的简化示例:
// main.go
package main
import "fmt"
const Version = "1.0.0"
func main() {
fmt.Println("Version:", Version)
}
// helper/helper.go
package helper
import "fmt"
const Version = "1.0.0"
func PrintVersion() {
fmt.Println("Helper Version:", Version)
}
// helper/helper_test.go
package helper
import "testing"
func TestPrintVersion(t *testing.T) {
PrintVersion()
}
使用覆盖率测试命令:
go test -coverprofile=coverage.out -coverpkg=./...,./helper/... ./... ./helper/...
这会触发类似的重复符号错误:
duplicate symbol go.constinfo.Version (types 45 and 45) in main and helper
解决方案:
- 使用更精确的包路径,避免包路径重叠:
go test -coverprofile=coverage.out -coverpkg=./helper ./helper
- 分别测试每个包,然后合并覆盖率结果:
go test -coverprofile=cmd.out -coverpkg=./cmd/... ./cmd/...
go test -coverprofile=lib.out -coverpkg=./lib/... ./lib/...
- 使用工具合并覆盖率文件:
gocovmerge cmd.out lib.out > coverage.out
对于syncthing项目,建议的测试命令:
# 分别测试cmd和lib目录
go test -short -coverprofile=cmd.out -coverpkg=./cmd/... ./cmd/...
go test -short -coverprofile=lib.out -coverpkg=./lib/... ./lib/...
# 合并覆盖率结果(需要安装gocovmerge)
go get github.com/wadey/gocovmerge
gocovmerge cmd.out lib.out > coverage.out
这个问题的根本修复需要在Go编译器中实现,但在当前版本中,通过分离测试目标可以避免重复符号错误。

