golang学习手册之build子命令(下)
build多个导入路径
前面介绍build命令时,对象都是单个的,接下来看看如果同时build多个对象会怎样,要分为三种情况:多个目录,多个文件,以及目录和文件共存。
目录和文件共存
如果同时build目录和文件
1 | ➜ examples go build ./test.go temp/ |
完全不可行,只要编译对象中出现了以“.go”为名字后缀的源代码文件,其他对象就不能是目录。
多个文件
文件列表必须全部都是go源代码文件,不能包含其他类型的文件。
1
2➜ example7 go build test.txt example7.go
named files must be .go files: test.txt同时.go文件和.txt文件直接报错了:要求所有文件只能是go文件。
所有文件必须来自同个目录。
1
2➜ example7 go build example7.go dir0/tmp.go
named files must all be in one directory; have . and dir0
同时编译当前目录下的examle7.go和子目录dir0下的tmp.go,就会报错:要求所有文件位于同一目录。
所有文件还必须属于同一个包。
1
2
3
4
5
6
7
8
9
10
11
12➜ example7 cat example7.go
package example7
func test() {
}
➜ example7 cat main.go
package main
func main() {
}
➜ example7 go build .
found packages example7 (example7.go) and main (main.go) in /home/Admin/projects/examples/example7main.go和examle7.go都位于当前目录,但是在代码中声明了不同的包,所以报错:在目录中发现了两个不同的包。
换言之,同一个目录下的源代码文件属于不同的包时,无法同时编译,只能分开编译,无论是以目录形式还是以文件列表形式。当多个go文件来自同个目录,都属于非main包,那么编译这些文件跟直接编译他们所在的目录是一样的效果。
当多个go文件来自同个目录,都属于属于main包。
区别在于默认生成的可执行文件的名字:直接编译目录默认以目录命名,编译文件列表默认以第一个文件的名字命名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16➜ example7 cat example7.go
package example7
func test() {
}
➜ example7 cat main.go
package main
func main() {
}
➜ example7 go build example7.go main.go
➜ example7 ls
dir0 example7 example7.go main.go
➜ example7 go build main.go example7.go
➜ example7 ls
dir0 example7 example7.go main main.go
main.go和example7.go只是换了一下位置,生成的可执行文件名就不一样了。
多个目录
若某个目录不存在go文件
1
2
3
4
5
6
7
8
9➜ example8 tree .
.
├── tmp1
│ └── tmp.go
└── tmp2
2 directories, 1 file
➜ example8 go build ./tmp1 ./tmp2
package ./tmp2: no Go files in /home/Admin/projects/examples/example8/tmp2直接报错了。
所有目录都包含了go文件,不过由于来自不同目录,是否属于同一个包已经没有意义了,即使所属的包名相同,也不会被视为同一个包。此时进行编译,也就是进行个语法检查而已,除非还要使用-o参数。
1
2
3
4
5
6
7
8
9
10
11
12
13➜ example8 cat tmp1/tmp.go
package main
func main() {
}
➜ example8 cat tmp2/tmp.go
package main
func main() {
}
➜ example8 go build ./tmp1 ./tmp2
➜ example8 ls
tmp1 tmp2即使tmp1和tmp2目录中的代码都声明了自己属于main包,一起进行编译时,也不会生成可执行文件,仅仅做语法检查。可以知道对于部分目录是非main包,甚至所有目录全是非main包的情况了。
当使用-o参数时,又分为以下几种情况
所有目录都包含main包
1
2➜ example8 go build -o main ./tmp1 ./tmp2
go: cannot write multiple packages to non-directory main继续使用上面的代码,-o的参数值是文件,报错了,无法将两个包的可执行文件结果写入到一份文件中,所以此时-o的参数值只能是目录:
1
2
3➜ example8 go build -o tmp/ ./tmp1 ./tmp2
➜ example8 ls tmp
tmp1 tmp2在新建的目录tmp中,分别为两个目录的代码生产了各自的可执行文件,这也印证了上面的说法,即两个目录的代码即使声明为同一个包,也会被build命令分开处理,而不是当做同一个包。
所有目录都不包含main包
1
2
3
4
5
6
7
8
9
10
11
12
13
14➜ example8 cat tmp3/tmp3.go
package example8
func tmp() {
}
➜ example8 cat tmp4/tmp4.go
package example8
func tmp() {
}
➜ example8 go build -o pkg ./tmp3 ./tmp4
go: cannot write multiple packages to non-directory main
➜ example8 go build -o tmp ./tmp3 ./tmp4
go: no main packages to build无论-o参数值是文件还是目录,都报错了,这意味着此时只能做语法检查。
部分目录包含main包
1
2
3
4
5➜ example8 go build -o main ./tmp1 ./tmp3
go: cannot write multiple packages to non-directory main
➜ example8 go build -o temp/ ./tmp1 ./tmp3
➜ example8 ls temp
tmp1继续使用前面的代码,可以发现,即使某个目录中存在main包,也无法将编译结果保存到文件中;但是却可以将main包的编译结果保存到指定目录中,当然非main包的那些代码生成的库文件会被丢弃。
(全文完)