比如当前目录是$GOPATH/src/GO1209,当前目录有个文件夹dirmain是一个包,如果指定包的文件夹进行编译,会报错输出文件dirmain在当前目录已经存在并且是个目录:
VMCatalina:src haypin$ tree Go1209
Go1209
├── dirmain
│ ├── go.mod
│ ├── gomain.go
│ ├── gomain2.go
│ └── gomain3.go
VMCatalina:src haypin$
VMCatalina:Go1209 haypin$ go build Go1209/dirmain
go build: build output "dirmain" already exists and is a directory
因为不论在Windows还是在Linux或者在Unix中,目录也是个文件,其中存储着目录中内容(子目录或文件)的名字——文件节点指针的映射,具体参考《鸟哥的Linux私房菜》基础篇讲解文件系统部分,因此同一目录下的子目录和文件不允许重名。
解决办法:
1、通过-o [output]选项指定生成文件名使不与子目录重名:
VMCatalina:Go1209 haypin$ go build -o pkgmain Go1209/dirmain
VMCatalina:Go1209 haypin$ tree ../Go1209
../Go1209
├── dirmain
│ ├── go.mod
│ ├── gomain.go
│ ├── gomain2.go
│ └── gomain3.go
├── pkgmain
VMCatalina:Go1209 haypin$
这里还有一个有意思的地方,如果-o [output]选项指定的生成文件名与包文件夹名最后一段同名,则会输出生成文件到包文件夹下,Go还是很聪明的,不会自己犯蠢:
VMCatalina:Go1209 haypin$ go build -o dirmain Go1209/dirmain
VMCatalina:Go1209 haypin$ tree ../Go1209
../Go1209
├── dirmain
│ ├── dirmain
│ ├── go.mod
│ ├── gomain.go
│ ├── gomain2.go
│ └── gomain3.go
VMCatalina:Go1209 haypin$
2、这还不简单,新建一个文件夹然后cd到新建文件夹再编译生成,那生成文件就在pwd下了:
VMCatalina:Go1209 haypin$ mkdir tempDir
VMCatalina:Go1209 haypin$ cd tempDir
VMCatalina:tempDir haypin$ go build Go1209/dirmain
VMCatalina:tempDir haypin$ cd ..
VMCatalina:Go1209 haypin$ tree ../Go1209
../Go1209
├── dirmain
│ ├── dirmain
│ ├── go.mod
│ ├── gomain.go
│ ├── gomain2.go
│ └── gomain3.go
└── tempDir
└── dirmain
VMCatalina:Go1209 haypin$