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的情况。

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之前确实是标准做法。

注意:

  1. 如果bar有自己的go.mod,它就是一个独立的模块,应该从其目录内构建
  2. 使用go build ./bar时,Go会识别bar目录中的go.mod并作为独立模块处理
  3. 从Go 1.20开始,推荐使用-C标志来避免子shell操作

根据您的Go版本选择合适的方法。对于go1.13.3,使用子shell(cd bar && go build)是正确的做法。

回到顶部