Golang中如何在不改变工作目录的情况下正确使用`go build`语法构建子目录中的主模块?
Golang中如何在不改变工作目录的情况下正确使用go build语法构建子目录中的主模块?
假设我在Bash shell中,工作目录为~/projects/foo(该目录可能包含一个go.mod文件)。在GO111MODULE=on的情况下,我该如何构建位于~/projects/foo/bar(该目录也包含一个go.mod文件)的主模块?
唯一似乎可行(但感觉不太对劲)的方法是(cd foo && go build)。这是在Kubuntu上使用go1.13.3的情况。
您要找的命令是:go build -o hello ./bar。编译后的程序将命名为 hello,并存储在您执行该命令时所在的目录中。
如果没有 -o hello,该命令将尝试创建一个名为 bar 的程序。它会失败,因为您执行命令的目录中已存在一个同名目录。
func main() {
fmt.Println("hello world")
}
更多关于Golang中如何在不改变工作目录的情况下正确使用`go build`语法构建子目录中的主模块?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
观察得很仔细。不过,在那之前我还犯了另一个错误。由于我在要构建项目的父目录中执行 go build,该目录的 go.mod 总是被优先考虑。通过运行 go mod edit -replace example.com/me/foo/bar=./bar,我才走到了需要实现你解决方案的这一步,即能够使用 go build -o bar/bar example.com/me/foo/bar 来构建项目。另外,了解到这一点也很好:Git 仓库中的子模块使用 bar/vX.Y.Z 形式的标签进行版本控制。解决方案在这里找到:https://github.com/golang/go/issues/27056
go build -o bar/bar example.com/me/foo/bar
在Go模块模式下,您可以使用-C标志(从Go 1.20开始引入)来指定工作目录,或者使用go build的模块路径参数。以下是几种正确的方法:
方法1:使用-C标志(Go 1.20+)
go build -C bar .
-C bar会切换到bar目录执行构建,最后的.表示构建当前目录(即bar)。
方法2:使用模块路径参数
go build ./bar
如果bar是主模块的子目录,这会构建bar目录中的包。如果bar有独立的go.mod,需要明确指定模块路径。
方法3:使用完整模块路径
go build ~/projects/foo/bar
或者使用相对路径:
go build ./foo/bar
方法4:使用go run的替代方式(适用于构建并运行)
go run ./bar
示例代码结构:
假设您的项目结构如下:
~/projects/foo/
├── go.mod
└── bar/
├── go.mod
└── main.go
要构建bar中的主模块,最直接的方法是:
cd ~/projects/foo
go build ./bar
如果bar是独立的模块(有自己的go.mod),并且您不想切换目录,可以使用:
cd ~/projects/foo
(cd bar && go build)
这种方法虽然您觉得"不太对劲",但在Go 1.20之前确实是标准做法。
注意:
- 如果
bar有自己的go.mod,它就是一个独立的模块,应该从其目录内构建 - 使用
go build ./bar时,Go会识别bar目录中的go.mod并作为独立模块处理 - 从Go 1.20开始,推荐使用
-C标志来避免子shell操作
根据您的Go版本选择合适的方法。对于go1.13.3,使用子shell(cd bar && go build)是正确的做法。

