英文:
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
,但是使用它时,我只能为子模块构建可执行文件,而不能为主模块构建。
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.
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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论