Go构建工程入门1(了解即可,现在推荐使用Go module)
在Go的官网文档How to Write Go Code中,已经介绍了Go的项目目录一般包含以下几个:
- src 包含项目的源代码文件;
- pkg 包含编译后生成的包/库文件;
- bin 包含编译后生成的可执行文件。
一般,bin和pkg目录可以不创建,go命令会自动创建(如 go install),只需要创建src目录即可。对于pkg目录,一开始我犯了这样的错误——”我把Go中的包放入pkg下面,怎么不行啊?“我直接把Go包的源文件放入了pkg中。这显然是不对的。pkg中的文件是Go编译生成的(一般文件后缀.a),而不是手动放进去的。
下面以一个简单的例子进行说明。(Windows环境,在命令行下进行实验,而不是使用IDE。我使用的终端工具是cmder)
当前的项目在D:\workspace\godemo下,其目录结构如下:
├─godemo
│ └─src
│ ├─config
| |-- config.go
│ └─main
| |-- main.go
源文件如下:
// config.go
package config
import "fmt"
func LoadConfig() {
fmt.Println("loading config...")
}
// main.go
package main
import (
"fmt"
"config"
)
func main() {
config.LoadConfig()
fmt.Println("this is main pkg")
}
此时使用 go build 进行构建,会发生如下错误:
D:\workspace\godemo
λ go build src\main\main.go
src\main\main.go:5:2: cannot find package "config" in any of:
D:\soft\Go\src\config (from $GOROOT)
D:\workspace\goshop\src\config (from $GOPATH)
从输出中我们可以看到,Go先是从 \(GOROOT** 中查找包"config",如果没找到,就从 **\)GOPATH 中查找,结果都没有找到。
我们可以使用 go env 输出Go的环境变量设置,如下:
λ go env
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\mao\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=D:\workspace\goshop
set GOPROXY=
set GORACE=
set GOROOT=D:\soft\Go
set GOTMPDIR=
set GOTOOLDIR=D:\soft\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
...省略...
那么这里的GOROOT和GOPATH环境变量到底有何作用呢?在官方文档中已经说明:
The GOPATH environment variable specifies the location of your workspace. It defaults to a directory named go inside your home directory, so $HOME/go on Unix, $home/go on Plan 9, and %USERPROFILE%\go (usually C:\Users\YourName\go) on Windows.
If you would like to work in a different location, you will need to set GOPATH to the path to that directory. (Another common setup is to set GOPATH=$HOME.) Note that GOPATH must not be the same path as your Go installation.
GOPATH 环境变量明确了工作目录的位置,在Windows环境下,默认的GOPATH为%USERPROFILE%\go (通常为 C:\Users\YourName\go),由于我在最初安装Go的时候修改这一值,从上面可以看到,我的GOPATH为 D:\workspace\goshop 。但此时,我的项目并非构建在这个目录下,所以导包的时候系统无法找到。
我们可以通过如下命令设置,修改成新的环境变量。
setx GOPATH "%GOPATH%;D:\workspace\godemo"
(注:这个命令会针对GOPATH环境变量追加写入一个新的变量值,即"D:\workspace\godemo",此外还可以在图形化界面中添加新的GOPATH值。执行该命令后应重启控制台,以便让环境变量生效。)
通过执行 go env GOPATH 命令(该命令查看系统当前可用的 GOAPTH 路径),如下:
D:\workspace\godemo
λ go env GOPATH
D:\workspace\goshop;D:\workspace\godemo
此时再次执行 go build 命令,就不会出错了。如下:
D:\workspace\godemo
λ go build src\main\main.go
D:\workspace\godemo
λ ls
main.exe* src/
D:\workspace\godemo
λ main.exe
loading config...
this is main pkg
虽然运行成功,可执行文件main.exe并不是生成在bin目录下(这似乎并不符合本文开头所述),而是生成在执行 go build 这条语句的相应目录下。为了符合规范,则需要使用 go install 工具。命令go install 用于编译并安装指定的代码包及它们的依赖包。当指定的代码包的依赖包还没有被编译和安装时,该命令会先去处理依赖包。与go build命令一样,传给go install命令的代码包参数应该以导入路径的形式提供。并且,go build命令的绝大多数标记也都可以用于go install命令。实际上,go install命令只比go build命令多做了一件事,即:安装编译后的结果文件到指定目录。
D:\workspace\godemo
λ ls
src/ # --> 当前目录下只有 src/
D:\workspace\godemo
λ go install src\config\
can't load package: package src/config: cannot find package "src/config" in any of:
D:\soft\Go\src\src\config (from $GOROOT)
D:\workspace\goshop\src\src\config (from $GOPATH)
D:\workspace\godemo\src\src\config
D:\workspace\godemo
λ go install config\ main\ # --> go install 后面直接跟包名
D:\workspace\godemo
λ ls
bin/ pkg/ src/ # --> 最后生成了 bin/ pkg/ 目录
现在整个项目的目录结构如下:
├─godemo
| └─bin
| |-- main.exe
| └─pkg
| |-- windows_amd64
| |-- config.a*
│ └─src
│ ├─config
| |-- config.go
│ └─main
| |-- main.go
(全文完)
参考:
1、https://golang.org/doc/code.html#Workspaces (官方文档)
2、https://blog.csdn.net/belalds/article/details/80076817