修改Go cmd/compile/internal/syntax/tokens.go后进行generate的问题

我修改了GO的源码,比如compiler下的tokens.go,然后调用 go generate 去生成代码,但是不管如何修改tokens.go ,生成的代码始终都是一样的。

我的环境:

  1. MacOS 10.14.3
  2. clone源码目录: /Volumes/Samsung_T5/projects/go
  3. go二进制版本安装在/usr/local/go里,版本为: go version go1.14.4 darwin/amd64

对应的go env如下:

(dev) [w@me syntax]$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/allwefantasy/Library/Caches/go-build"
GOENV="/Users/allwefantasy/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/allwefantasy/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="/Volumes/Samsung_T5/projects/go/src/cmd/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/3n/bhwn_3d14k34bvzm3nyxnv_h0000gn/T/go-build452591877=/tmp/go-build -gno-record-gcc-switches -fno-common"

设置GOROOT为源码目录后会报错。不设置,则修改tokens.go后,比如operator_string.go 每次生成的都是一样。会生成,但是内容一样。

我看了下,和这个issue描述的很相似:

可能有些环境变量需要设置。试试用 make.bash 编译呢?

我尝试修改 tokens.go里的operator:

type Operator uint

//go:generate stringer -type Operator -linecomment

const (
	_ Operator = iota

	// Def is the : in :=
	Def  // :
	Not  // !
	Recv // <-

	// precOrOr
	OrOr  // ||
	ExtOr // or

	// precAndAnd
	AndAnd // &&
	ExtAnd // and

添加了 ExtOr, ExtAnd ,接着运行

./make.bash

能够成功运行,并且将go二进制文件放到项目更目录里的bin目录里了。

但是打开operator_string.go 貌似依然没有变化:

package syntax

import "strconv"

const _Operator_name = ":!<-||&&==!=<<=>>=+-|^*/%&&^<<>>"

var _Operator_index = [...]uint8{0, 1, 2, 4, 6, 8, 10, 12, 13, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 30, 32}

然后我修改了 noder.go里的代码:

func parseFiles(filenames []string) uint {
	noders := make([]*noder, 0, len(filenames))
	// Limit the number of simultaneously open files.
	sem := make(chan struct{}, runtime.GOMAXPROCS(0)+10)

	for _, filename := range filenames {
		println(filename)
		p := &noder{
			basemap: make(map[*syntax.PosBase]*src.PosBase),
			err:     make(chan syntax.Error),
		}

增加了一行打印输出。在编译编译器的时候,确实会输出。

我运行了src目录下的dist:

(dev) [w@me src]$ GOROOT=/Volumes/Samsung_T5/projects/go ./cmd/dist/dist env -p
GOARCH="amd64"
GOBIN="/Volumes/Samsung_T5/projects/go/bin"
GOCACHE="/Volumes/Samsung_T5/projects/go/pkg/obj/go-build"
GODEBUG=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPROXY=""
GOROOT="/Volumes/Samsung_T5/projects/go"
GOTMPDIR=""
GOTOOLDIR="/Volumes/Samsung_T5/projects/go/pkg/tool/darwin_amd64"
PATH="/Volumes/Samsung_T5/projects/go/bin:/anaconda3/envs/dev/bin:/Users/allwefantasy/.cargo/bin:/anaconda3/condabin:/anaconda3/bin:/Users/allwefantasy/.nvm/versions/node/v10.5.0/bin:/usr/local/opt/protobuf@2.5/bin:/Users/allwefantasy/go/bin:/Users/allwefantasy/nlp_architect_env/bin:/Users/allwefantasy/Softwares/apache-maven-3.6.1/bin:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin:/bin:/bin:/bin:/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/usr/local/MacGPG2/bin:/opt/X11/bin:/Users/allwefantasy/Softwares/sbt/bin:/Users/allwefantasy/Softwares/antlr:/Users/allwefantasy/bin"

是有点奇怪。这个输出头 // Code generated by “stringer -type Operator -linecomment”; DO NOT EDIT. 和自带的stringer的输出不太一样。

你可以到 golang nuts 上问问。

在dig make.bash的整个流程,

分三个步骤:

  1. 检查环境
  2. 通过go 编译./cmd/dist/dist 二进制文件(相当于一个构建工具)
  3. 使用dist可执行文件构建go

然后我看看dist的实现,找找问题。

补充: 最后莫名其妙好了;但是大致原因可能是我挂的外挂固态硬盘有关系。