英文:
golang: core net/http package import errors
问题
我使用 git clone https://go.googlesource.com/go
将 go源代码 克隆到了 ~/godev/
目录下(根据文档的建议,放在了GOPATH之外)。
我的 $GOPATH 是 ~/gocode
。
我使用官方的OSX安装程序安装了go 1.8.1。
如果我进入 ~/godev/go/src/net/http
目录并运行 go test
,会出现以下错误:
h2_bundle.go:46:2: 找不到包 "golang_org/x/net/http2/hpack",在以下任何位置都找不到:
/usr/local/go/src/golang_org/x/net/http2/hpack(来自$GOROOT)
~/gocode/src/golang_org/x/net/http2/hpack(来自$GOPATH)
h2_bundle.go:47:2: 找不到包 "golang_org/x/net/idna",在以下任何位置都找不到:
/usr/local/go/src/golang_org/x/net/idna(来自$GOROOT)
~/gocode/src/golang_org/x/net/idna(来自$GOPATH)
h2_bundle.go:48:2: 找不到包 "golang_org/x/net/lex/httplex",在以下任何位置都找不到:
/usr/local/go/src/golang_org/x/net/lex/httplex(来自$GOROOT)
~/gocode/src/golang_org/x/net/lex/httplex(来自$GOPATH)
transport.go:32:2: 找不到包 "golang_org/x/net/proxy",在以下任何位置都找不到:
/usr/local/go/src/golang_org/x/net/proxy(来自$GOROOT)
~/gocode/src/golang_org/x/net/proxy(来自$GOPATH)
transfer.go:14:2: 不允许使用内部包
按照这里的说明,我执行了 cd $GOPATH/src
,然后执行了 cp -R /usr/local/go/src/vendor/golang_org .
,但仍然出现以下错误:
h2_bundle.go:47:2: 目录 ~/gocode/src/golang_org/x/net/idna 中的代码期望导入 "golang.org/x/net/idna"
transport.go:32:2: 找不到包 "golang_org/x/net/proxy",在以下任何位置都找不到:
/usr/local/go/src/golang_org/x/net/proxy(来自$GOROOT)
~/gocode/src/golang_org/x/net/proxy(来自$GOPATH)
transfer.go:14:2: 不允许使用内部包
确实,在 ~/gocode/src/golang_org/x/net 目录下没有 proxy 包,但我仍然不知道如何修复这个问题和其他两个错误。
以下是我的环境变量设置:
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="~/gocode"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/71/k_tftg2d1qd7gf5ww0n_wl_r0000gn/T/go-build541211050=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
如果我运行 all.bash 脚本,将运行所有单元测试,但这需要很长时间。有没有办法只运行 net/http 的测试而不出现这些错误?
英文:
I've cloned go source code using git clone https://go.googlesource.com/go
into my ~/godev/
directory (outside of GOPATH as the docs advise).
My $GOPATH is ~/gocode
I installed go 1.8.1 using the official osx installer.
If I cd into ~/godev/go/src/net/http
and run go test
, I get these errors:
h2_bundle.go:46:2: cannot find package "golang_org/x/net/http2/hpack" in any of:
/usr/local/go/src/golang_org/x/net/http2/hpack (from $GOROOT)
~/gocode/src/golang_org/x/net/http2/hpack (from $GOPATH)
h2_bundle.go:47:2: cannot find package "golang_org/x/net/idna" in any of:
/usr/local/go/src/golang_org/x/net/idna (from $GOROOT)
~/gocode/src/golang_org/x/net/idna (from $GOPATH)
h2_bundle.go:48:2: cannot find package "golang_org/x/net/lex/httplex" in any of:
/usr/local/go/src/golang_org/x/net/lex/httplex (from $GOROOT)
~/gocode/src/golang_org/x/net/lex/httplex (from $GOPATH)
transport.go:32:2: cannot find package "golang_org/x/net/proxy" in any of:
/usr/local/go/src/golang_org/x/net/proxy (from $GOROOT)
~/gocode/src/golang_org/x/net/proxy (from $GOPATH)
transfer.go:14:2: use of internal package not allowed
After I follow the directions here by doing cd $GOPATH/src
followed by
cp -R /usr/local/go/src/vendor/golang_org .
, I still get these errors:
h2_bundle.go:47:2: code in directory ~/gocode/src/golang_org/x/net/idna expects import "golang.org/x/net/idna"
transport.go:32:2: cannot find package "golang_org/x/net/proxy" in any of:
/usr/local/go/src/golang_org/x/net/proxy (from $GOROOT)
~/gocode/src/golang_org/x/net/proxy (from $GOPATH)
transfer.go:14:2: use of internal package not allowed
It is true that there is no proxy package under ~/gocode/src/golang_org/x/net, but I still don't know how to fix that and the other 2 errors.
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="~/gocode"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/71/k_tftg2d1qd7gf5ww0n_wl_r0000gn/T/go-build541211050=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
If I run the all.bash script, it will run all unit tests, but that is time consuming. Is there a way to run just net/http tests without getting these errors?
答案1
得分: 4
问题在于你正在运行go test
,其中go
命令是你的1.8.1版本安装。为了使测试正常工作,你应该使用从开发目录构建的Go工具链来运行。
- 确保你已经构建了Go工具链,
cd ~/godev/src; ./make.bash
(./all.bash
也可以,但是你需要等待测试运行完成而不仅仅是构建工具链)。 - 使用新编译的工具链运行测试,
cd ~/godev/src/net/http; ~/godev/bin/go test
。
我建议在你的配置文件中添加一个别名,比如alias godev=~/godev/bin/go
,这样你就可以运行godev test
。
还要确保你没有设置GOROOT
环境变量,因为它会导致go
命令使用指定的路径作为GOROOT,而不管你正在使用哪个工具链,这不是你想要的。
更新
根据评论中的要求,我尽量提供简明的解释:
-
提到“cannot find package”的错误是因为它们在
~/godev/src/vendor/golang_net/...
中寻找一些包,但是1.5/1.6中添加的供应支持只在包位于GOPATH或GOROOT内时起作用。你的godev安装不在GOPATH内(也不应该在其中),而GOROOT指向你的1.8.1安装。 -
transfer.go:14:2: use of internal package not allowed
是因为transfer.go
导入了net/http/internal
。由于这不是一个相对路径,它将在$GOROOT/src/net/http/internal
中找到,而不是~/godev/src/net/http/internal
,如果导入包的包与内部目录没有共同的根目录,就无法导入内部包。
问题归结为GOROOT指向你的1.8.1安装。你可能会想是否可以将GOROOT设置为指向你的godev目录,但这也不会正常工作。我对这里的机制不太确定,但我认为问题在于1.8.1编译器期望的内容与~/godev/src/runtime
中的内容不匹配。
当编译工具链时,GOROOT的位置被编译进去,所以当运行~/godev/bin/go
时,它将使用~/godev
作为它的GOROOT。
英文:
The problem here is that you're running go test
, where the go
command is your 1.8.1 installation. For the tests to work properly you should run with the Go toolchain built from your development directory.
- Make sure you've built the Go toolchain,
cd ~/godev/src; ./make.bash
(./all.bash
will work too, but then you'll have to wait for tests to run instead of just building the toolchain). - Run the tests with the newly compiled toolchain,
cd ~/godev/src/net/http; ~/godev/bin/go test
.
I suggest adding an alias to your profile, such as alias godev=~/godev/bin/go
, then you can run godev test
.
Also make sure that you are not setting the GOROOT
environment variable as it will cause the go
command to use the specified path as the GOROOT regardless of which toolchain you're running with, which is not what you want.
Update
As requested in the comments, here's as brief an explaination as I can come up with:
-
The errors that mention "cannot find package" are looking for some packages that are vendored in
~/godev/src/vendor/golang_net/...
. However, the vendoring support added in 1.5/1.6 only works when the package is inside the GOPATH or GOROOT. Your godev installation is not (and should not be) inside GOPATH and GOROOT is pointing to your 1.8.1 install. -
transfer.go:14:2: use of internal package not allowed
is becausetransfer.go
importsnet/http/internal
. Since this is not a relative path it'll be found in$GOROOT/src/net/http/internal
, instead of~/godev/src/net/http/internal
and internal packages cannot be imported if the importing package does not share a common root with the internal directory.
It boils down to GOROOT pointing to your 1.8.1 installation. You might wonder if you could just set GOROOT to point at your godev directory, but this is not going to work correctly either. I'm not as certain of the mechanics here, but I think the problems come down to mismatches between what the 1.8.1 compiler expects are what is in ~/godev/src/runtime
.
When the toolchain is compiled the location of GOROOT is compiled in, so when ~/godev/bin/go
is run, it uses ~/godev
as it's GOROOT.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论