当与工作区一起使用时,go build无法正常工作。

huangapple go评论76阅读模式
英文:

go build not working when used with workspaces

问题

以下是我的golang代码结构:

├── go.work
├── moda
│   ├── go.mod
│   └── main.go
├── go.mod
└── modb
    └── main.go

问题是我只能为单个模块构建二进制文件。对于构建其他模块,只有在我将其他模块在go.work中注释掉后才能正常工作。

我的go.work如下:

go 1.19
use (
    ./moda
    .
)

所以当我使用上述go.work进行以下构建时,它可以正常工作:

go build -o test-binary -modfile ./moda/go.mod ./moda

但是当我尝试为我的其他模块(即modb/)进行以下构建时:

go build -o test-binary1 -modfile ./go.mod ./modb

我遇到以下错误:

目录modb包含在一个不在go.work中列出的工作区模块中。您可以使用go work use将该模块添加到工作区。

我尝试使用go work use,但仍然遇到相同的问题。有人可以帮助我解决这个问题吗?

编辑1:

我有一个项目,需要多个go.mod文件来分离主模块和子模块的依赖关系,这时我了解到了go工作区,它完美地适用于我的用例。

我的项目结构与上面提到的相同:

├── go.work
├── submodule
│   ├── go.mod
│   ├── go.sum
│   └── main.go
└── mainmodule
    └── main.go
├── go.mod
├── go.sum

现在,当为子模块构建可执行文件时,go build可以正常工作,但是当为主模块构建可执行文件时,子模块/go.mod中的导入也会添加到主模块的可执行文件中。我还使用go build -n进行了验证。

为了避免将子模块的导入添加到主模块的可执行文件中,我使用了-modfile,但是使用它时,我只能为子模块构建可执行文件,而不能为主模块构建。

github源码

PS:尽管我在github中添加了示例代码,但无法重现相同的问题(子模块的导入被添加到主模块中),不确定是否是因为我使用的导入导致的。

英文:

Below is the structure of my golang code,

├── go.work
├── moda
│   ├── go.mod
│   └── main.go
├── go.mod
└── modb
    └── main.go

The problem is I'm only able to build binary only for a single module. For building other modules it is only working after i comment out the other modules in go.work

my go.work is as below,

go 1.19
use (
    ./moda
    .
)

so when i do build as below with the above go.work it works fine,

go build -o test-binary -modfile ./moda/go.mod ./moda

but when i try to build for my other module (which is modb/) like below,

go build -o test-binary1 -modfile ./go.mod ./modb

i'm getting below error,

> directory modb is contained in a module that is not one of the workspace modules listed in go.work. You can add the module to the workspace using go work use .

i tried using go work use but im still facing the same issue. Can someone help me solve this ?

edit 1:

I have a project that needs multiple go.mod files to separate the dependencies of main and submodules and thats when i got to know about go workspaces which worked perfectly for my use case.

The structure of my project is same as mentioned above,

├── go.work
├── submodule
│   ├── go.mod
│   ├── go.sum
│   └── main.go
└── mainmodule
    └── main.go
├── go.mod
├── go.sum

now when building executable for submodule go build works fine but when building executable for mainmodule the imports that are present in submodules/go.mod are also getting added to mainmodule executable. I have verified this with go build -n too.

To avoid the submodule imports getting added to mainmodule executable i used -modfile but using it i'm only able to build the executable for the submodule but not for mainmodule.

github source

PS: though i have added the example code in github it is not able to reproduce the same issue (submodule imports getting added to mainmodule) not sure if it is because of the imports i used though

答案1

得分: 1

经过与@ArigatoManga的讨论,我们发现混淆是由工作区中的最小版本选择(MVS)行为引起的。工作区是磁盘上的一组模块,当运行**最小版本选择(MVS)**时,它们被用作主要模块(参考:链接)。由于MVS的存在,启用工作区模式构建的模块可能会使用与禁用工作区模式构建的模块不同的依赖模块。

这是工作区的已记录行为,目前没有相关问题。


更新:下面是关于-modfile标志的原始回答,该标志将在go1.21的工作区模式中被拒绝。

您遇到了go工具中的一个错误。我刚刚在这里报告了这个问题(链接:https://github.com/golang/go/issues/59996)。

Go1.20中的错误消息不同,但仍然具有误导性:

go: module example.com/m1 appears multiple times in workspace

这个差异是由提交cmd/go/internal/modload: return error when duplicate module paths among modules in go.work引入的,但根本原因是相同的:在工作区模式下,-modfile标志没有被正确处理。


更新:下面的部分现在与问题无关。这是在了解MVC之前尝试使用-modfile标志来抑制MVS的失败尝试。

在问题报告中,我建议在工作区模式下禁止-modfile标志。但是您在评论中表示您需要此标志。

> 使用-modfile的原因是,如果我为./src构建二进制文件,则即使在./moda中也会下载并加载./src二进制文件中不应包含的模块。

但根据cmd/go文档

> -modfile file
>
> 在模块感知模式下,读取(可能还会写入)替代的go.mod文件,而不是模块根目录中的文件。仍然必须存在名为"go.mod"的文件以确定模块根目录,但不会访问它。当指定了-modfile时,还会使用替代的go.sum文件:其路径是通过修剪.mod扩展名并追加.sum来派生的。

-modfile标志用于替换模块根目录中的go.mod文件。但在您的示例中,您指定的文件与模块根目录中的文件相同。所以我不太理解。您能否更新您的问题以详细说明这部分内容?最好提供一个示例!

英文:

After a discussion with @ArigatoManga, we found that the confusion is caused by the behavior of minimal version selection (MVS) in workspace. A workspace is a collection of modules on disk that are used as the main modules when running minimal version selection (MVS) (reference). Because of the MVS, a module built with the workspace mode enabled could use different dependent modules from the one built with the workspace mode disabled.

This is a documented behavior of the workspace, and there is not issue about it now.


Update: Below is the original answer focusing on the -modfile flag. This flag will be rejected in workspace mode in go1.21.

You have run into a bug in the go tools. I just reported this issue here.

The error message in Go1.20 is different and still misleading:

go: module example.com/m1 appears multiple times in workspace

The difference was introduced by the commit cmd/go/internal/modload: return error when duplicate module paths among modules in go.work, but the root cause is the same: in workspace mode, the -modfile flag is not handled correctly.


Update: The part below is not relevant now. It's a failed try to suppress MVS with the -modfile flag before understanding what MVC is.

In the issue report, I suggested to prevent the -modfile flag in workspace mode. But you said that you need this flag in the comment.

> the reason for using -modfile is without that if i build binary for ./src the modules present even in ./moda are also getting downloaded and loaded as part of ./src binary though they should not be included

But according to the cmd/go doc:

> -modfile file
>
> in module aware mode, read (and possibly write) an alternate go.mod
file instead of the one in the module root directory. A file named
"go.mod" must still be present in order to determine the module root
directory, but it is not accessed. When -modfile is specified, an
alternate go.sum file is also used: its path is derived from the
-modfile flag by trimming the ".mod" extension and appending ".sum".

The -modfile flag is used to replace the go.mod file in the module root. But in your example, you specify the same file as the one in the module root. So I don't quite understand it. Can you update your question to elaborate this part? A demo is appropriated!

huangapple
  • 本文由 发表于 2023年5月4日 22:46:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76174480.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定