Go项目目录管理

Go的官网文档How to Write Go Code中,已经介绍了Go的项目目录一般包含以下几个:

  • src 包含项目的源代码文件;
  • pkg 包含编译后生成的包/库文件;
  • bin 包含编译后生成的可执行文件。

可以通过下面的例子来说明工程目录的组织管理。(Windows 7 64位,go version go1.3.3 windows/amd64)

1. 创建一个库文件

创建一个库文件a.go并保存在scr目录的一个子目录下面。

package myfunc

import "fmt"

func Afunc(str string) {
	fmt.Println("a.go is package mufunc.")
	fmt.Println(str)
}

这时候目录结构如下:

<dirtest>
     |--<src>
          |--<mufunc>
                 |--a.go

2. 创建main

关于main包的位置,可以参照参考资料2,个人建议放在scr/main下面,毕竟官方推荐包名和文件存放的文件夹名称最好相同(虽然包名和文件夹名可以不相同,也就是说一个文件夹下可以包含多个包的.go文件)。

package main

import "myfunc"

func main() {
	myfunc.Afunc("b.go is package main.")
}

这时候目录结构如下:

<dirtest>
     |--<src>
          |--<mufunc>
                 |--a.go
          |--<main>
                 |--b.go

3. 使用go build

如果这时候使用go build,你会发现下面的输出:

E:\dirtest>go build src\main\b.go

src\main\b.go:3:8: cannot find package "myfunc" in any of:
        C:\Program Files\go\src\pkg\myfunc (from $GOROOT)
        D:\GoLang\src\myfunc (from $GOPATH)

从输出中我们可以看到,Go先是从$GOROOT中查找包myfunc,如果没找到就从$GOPATH中查找,结果都没有找到,我们可以使用go env输出Go的环境变量设置:

E:\dirtest>go env

set GOARCH=amd64
set GOBIN=
set GOCHAR=6
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=D:\GoLang
set GORACE=
set GOROOT=C:\Program Files\go
set GOTOOLDIR=C:\Program Files\go\pkg\tool\windows_amd64
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1

显然E:\dirtest这个目录没有加到$GOPATH中,在环境变量中添加该目录:

保存后,重新执行(可能需要重新打开控制台,让环境变量生效)go build,就在当前目录生成了一个可执行文件b.exe

E:\dirtest\src\main>go env
set GOARCH=amd64
set GOBIN=
set GOCHAR=6
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=D:\GoLang;E:\dirtest
set GORACE=
set GOROOT=C:\Program Files\go
set GOTOOLDIR=C:\Program Files\go\pkg\tool\windows_amd64
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1

E:\dirtest>go build src\main\b.go
E:\dirtest>dir

 E:\dirtest 的目录

2015/01/13  23:11    <DIR>          .
2015/01/13  23:11    <DIR>          ..
2015/01/13  23:11    1,958,912      b.exe
2015/01/13  22:52    <DIR>          src

E:\dirtest>b.exe
a.go is package mufunc.
b.go is package main.

虽然成功运行,但是没有按照期待的那样生成在bin目录下面。为了达到这样的效果,你需要go install。注意go install是针对package,而不是针对单个.go文件。

但是如果是当前状态执行go install,虽然可以成功,但你会发现,并没有在项目根目录E:\dirtest中创建bin\main.exe,反而是在D:\GoLang中创建了。

如果对main包执行go install呢?

E:\dirtest\src\main>go install
go install: no install location for E:\dirtest\src\main: hidden by D:\GoLang\src
\main

可以看到,输出提示当前目录被隐藏。显然这个顺序是对应$GOPATH的设置的,把$GOPATH中的路径顺序改一下:

然后在执行go install myfunc,发现成功地在pkg目录下面生成了myfunc.a。同样执行go install main,也成功的在bin目录下生成了main.exe。此时的目录结构如下:

<dirtest>
     |--<src>
          |--<mufunc>
                 |--a.go
          |--<main>
                 |--b.go
     |--<pkg>
          |--<windows_amd64>
                 |--myfunc.a
     |--<bin>
          |--main.exe

现在就算是成功完成了一个示例“项目”吧...

4. 常见错误

除了上面的步骤中出现的错误,其实工程目录管理稍有不慎,就会出现其他问题,例如:

1. 一个文件夹下面包含多个不同包的源文件。也就是把a.gob.go都放到myfunc目录下面会是什么情况呢?

这时候的目录结构如下:

<dirtest>
     |--<src>
          |--<mufunc>
                 |--a.go
                 |--b.go

那么执行go installgo build,甚至go run都会是相同的错误:

E:\dirtest\src\myfunc>go install
can‘t load package: package myfunc: found packages myfunc (a.go) and main (b.go)
 in E:\dirtest\src\myfunc

E:\dirtest\src\myfunc>go build
can‘t load package: package myfunc: found packages myfunc (a.go) and main (b.go)
 in E:\dirtest\src\myfunc

E:\dirtest\src\myfunc>go run b.go
b.go:3:8: found packages myfunc (a.go) and main (b.go) in E:\dirtest\src\myfunc

从参考资料3中可以看到,每个子目录中只能存在一个package,否则编译时会报错,所以一个子目录下面不能包含多个不同包的源文件。

2. 一个项目能包含多个main()吗?

简单测试下,创建一个c.go,并使用myfunc包(没有导入其他包的情况类似):

package main
import "fmt"
import "myfunc"

func main() {
	fmt.Println("This is single c.go")
	myfunc.Afunc("c.go is also package main.")
}

执行相应的命令,结果如下:

E:\dirtest\src\main>go build
# main
.\c.go:4: main redeclared in this block
        previous declaration at .\b.go:5

E:\dirtest\src\main>go build c.go
# 成功,当前目录下生成了c.exe

E:\dirtest\src\main>go install
# main
.\c.go:4: main redeclared in this block
        previous declaration at .\b.go:5

E:\dirtest\src\main>go install c.go
go install: no install location for .go files listed on command line (GOBIN not
set)

E:\dirtest\src\main>go run c.go
This is single c.go
a.go is package mufunc.
c.go is also package main.

显然只能是go rungo build c.go可行。如果把c.go移到单独的目录下面呢:

E:\dirtest\src\cmain>dir

 E:\dirtest\src\cmain 的目录

2015/01/14  11:27    <DIR>          .
2015/01/14  11:27    <DIR>          ..
2015/01/14  11:24               147 c.go

E:\dirtest\src\cmain>go build

E:\dirtest\src\cmain>go install

均可以执行成功。go installbin目录下面生成了对应的exe文件。看来还是目录管理的问题。

3. go install: no install location for .go files listed on command line (GOBIN not set)

从上面的示例输出中就能看到,使用go install针对单个文件时,就会出现这个错误。默认情况下如果设置了$GOROOT$GOPATH,就会依次寻找$GOROOT/bin$GOPATH/bin。那么我们如果自定义设置了$GOBIN=E:\dirtest\bin之后会怎样?

E:\dirtest\src\cmain>go env
set GOARCH=amd64
set GOBIN=E:\dirtest\bin
set GOCHAR=6
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=E:\dirtest;D:\GoLang
set GORACE=
set GOROOT=C:\Program Files\go
set GOTOOLDIR=C:\Program Files\go\pkg\tool\windows_amd64
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1

E:\dirtest\src\cmain>go install c.go
# 成功在 E:\dirtest\bin 下面生成 c.exe

虽然成功了,但是go install应该是作用于包级别,而非单个文件。

4. go build、go install 和 go run 的区别

详细的可以查看参考资料4,这里简单说一下:

  • go build 编译包,如果是main包则在当前目录生成可执行文件,其他包不会生成.a文件;
  • go install 编译包,同时复制结果到$GOPATH/bin$GOPATH/pkg等对应目录下;
  • go run gofiles... 编译列出的文件,并生成可执行文件然后执行。注意只能用于main包,否则会出现go run: cannot run non-main package的错误。

此外,go run是不需要设置$GOPATH的,但go buildgo install必须设置。go run常用来测试一些功能,这些代码一般不包含在最终的项目中。

5. 总结

  1. 一定要管理好目录
  2. 多个项目最好都在一个$GOPATH下面,即src/proj1src/proj2,etc
  3. 尽量使用go install,这样能够规范项目整体结构

6. 参考资料

  1. Golang项目目录结构组织
  2. 关于main包放在哪的问题
  3. 关于golang中包(package)的二三事儿
  4. Running multi-file main package
时间: 2024-12-18 20:17:13

Go项目目录管理的相关文章

前端项目目录管理-部署结构

一.人生第一次做规划项目,以前都是跟着前端的老大,他把一切都规划好了,我跟着做就可以了,这次要自己规划前端目录结构,好紧张,参考了众多文章,结果还是看不太懂,百度前端工具框架–fis,没怎么看得懂,所以没用,还是自己好好想把,我还是主要参考了,我上次做项目时,那个项目负责人是怎么规划项目的. 二.前端结构 1.首先我想到需要的功能就是,把js.css.UI组件.库文件.grunt,等这些工具分开摆放. 2.在不考虑html文件的位置情况下,在任何地方都可以调用到js文件.css文件.UI组件.库

JavaWeb学习之tomcat安装与运行、tomcat的目录结构、配置tomcat的管理用户、web项目目录、虚拟目录、虚拟主机(1)

1.tomcat安装与运行双击tomcat目录下的bin/startup.bat,启动之后,输入http://localhost:8080,出现安装成功的提示,表示安装tomcat成功 2.tomcat的目录结构* bin目录:存放tomcat的启动和终止脚本 * startup.bat 启动脚本 * bootstrap.jar,启动脚本最终执行的java程序 * org.apache.catalina.startup.Bootstrap * shutdown.bat 终止脚本 * conf目录

基于Maven管理的JavaWeb项目目录结构参考

通常在创建JavaWeb项目时多多少少都会遵循一些既定的比较通用的目录结构,下面分享一张基于Maven管理的JavaWeb项目目录结构参考图: 上图仅是参考,不同项目不同团队都有自己的约定和规范. 个人体会: 项目目录结构一旦约定和规范之后,每个团队成员自我约束和遵守规范才是整个目录结构不随项目的进展而变得越来越不清晰的根本.

百度Baidu EFE team的前端规范——项目目录结构规范

项目目录结构规范 简介 该文档主要的设计目标是项目开发的目录结构保持一致,使容易理解并方便构建与管理. 编撰 李玉北.erik.黄后锦.王杨.张立理.赵雷.陈新乐.刘恺华. 本文档由商业运营体系前端技术组审校发布. 要求 在本文档中,使用的关键字会以中文+括号包含的关键字英文表示:必须(MUST).关键字"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT"

项目整体管理与范 围 管理

第六章项目整体管理 1.项目整体管理的7个过程: 1)      项目启动,制定项目章程. 2)      制定初步的项目范围说明书. 3)      制定项目管理计划. 4)      指导和管理项目的执行. 5)      监督和控制项目. 6)      整体变更控制. 7)      项目收尾. 2.项目章程应当包括11项内容(记忆7条以上) 1)      基于项目干系人的需求和期望提出的要求. 2)      项目必需满足的业务要求或产品需求. 3)      项目的目的或项目立项的

it项目沟通管理需要分类管理

it项目管理中沟通管理是重要的一部分.项目沟通不足,信息传递不及时,容易带来一系列的问题.问题频出,会打击团队成员的信心,导致工作效率和质量下降.因此做好沟通管理,必不可少.项目沟通管理不仅仅是指做好团队内部沟通管理,还需要做好其他干系人的沟通管理.由于涉及的不同角色的干系人,因此,做好分类管理,是做好it项目沟通管理的有效方法之一. 一.与信息系统供应商和此项目的具体负责人和信息部门人员的沟通 沟通原则:充分沟通.换位思考.通力合作,责任共担.成果共享.有了主要负责人和集团信息主管的实际参与,

第七章、Linux 文件与目录管理

1. 目录与路径 1.1 相对路径与绝对路径 1.2 目录的相关操作: cd, pwd, mkdir, rmdir 1.3 关於运行档路径的变量: $PATH 2. 文件与目录管理 2.1 文件与目录的检视: ls 2.2 复制.删除与移动: cp, rm, mv 2.3 取得路径的文件名称与目录名称 3. 文件内容查阅: 3.1 直接检视文件内容: cat, tac, nl 3.2 可翻页检视: more, less 3.3 数据撷取: head, tail 3.4 非纯文字档: od 3.5

2016年4月16日作业(项目整体管理、项目范围管理)

http://xuedalong.blog.51cto.com/1030946/1751965 1.请根据授课内容,梳理出今晚讲的重点.2.写出论文架构(不用写全文):论项目的计划与监控说明:对于中项学员只需完成第一题即可. 第6章,项目整体管理 1.项目整体管理的过程包括哪些内容?(记) 答:(1)项目启动 (2)制定初步的项目范围说明书 (3)制定项目管理计划 (4)指导和管理项目的执行 (5)监督和控制项目 (6)整体变更控制 (7)项目收尾 2.项目立项以后,就要正式启动项目.所谓的项目

鸟哥私房菜第七章 Linux文件与目录管理

一.目录与路径 1.相对路径与绝对路径 2.目录的相关操作 以下为特殊目录: .        :代表此目录 ..       :代表上一层目录 -        :代表前一个工作目录 ~       :代表"目前用户身份"所在的主文件夹 ~account :代表account这个用户的主文件夹 注:根目录下上一层(..)与前(.)是同一个目录. (1)cd:切换目录(change directory) 语法: [[email protected] ~]# cd [相对路径或绝对路径]