Home >Backend Development >Golang >go build doesn't work when used with workspace
php editor Banana is here to introduce to you a common problem, that is, the go build command cannot work properly when using the workspace. This problem may confuse developers, because the workspace is a very important concept in the Go language, and the inability to use the go build command properly will seriously affect the development process. In the following article, we will analyze the cause of this problem in depth and provide solutions to help developers successfully solve this problem.
The following is the structure of my golang code,
├── go.work ├── moda │ ├── go.mod │ └── main.go ├── go.mod └── modb └── main.go
The problem is that I can only build binaries for a single module. For building other modules, it only works if I comment out the other modules in go.work
My go.work is as follows,
go 1.19 use ( ./moda . )
So when I use the above go.work to build as follows, it works fine,
go build -o test-binary -modfile ./moda/go.mod ./moda
But when I try to build for my other modules (i.e. modb/) as shown below,
go build -o test-binary1 -modfile ./go.mod ./modb
I encountered the following 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 to work with use
but I'm still facing the same problem. Can anyone help me solve this problem?
Edit 1:
I had a project that required multiple go.mod files to separate the dependencies of the main module and submodules, and that's when I started learning about the go workspace which was a good fit for my use case.
My project structure is the same as mentioned above,
├── go.work ├── submodule │ ├── go.mod │ ├── go.sum │ └── main.go └── mainmodule └── main.go ├── go.mod ├── go.sum
Now, when building the executable for the submodule, go build works fine, but when building the executable for the main module, the imports present in the submodule/go.mod are also added to the main module executable middle. I also verified this with go build -n
.
To avoid adding submodule imports to the main module executable, I used -modfile
but using it I can only build the executable for the submodule and not for the main module document.
github source code
ps: Although I have added sample code in github, I cannot reproduce the same problem (submodule imports are added to the main module) Not sure if it is because of the imports I use
After discussing with @arigatomanga we found out that the confusion was caused by the minimum version selection (mvs) in the workspace. A workspace is a collection of modules on disk that is used as the main module when running Minimum Version Selection (mvs) (Reference). Thanks to mvs, modules built with workspace mode enabled can use different dependent modules than modules built with workspace mode disabled.
This is the recorded behavior of the workspace and there is no problem now.
Update: Below is the original answer, focusing on the -modfile
flag. In workspace mode in go1.21, this flag will be rejected.
You encountered an error in the go tool. 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 commit cmd/go/internal/modload: error returned when duplicate module path between modules in go.work, but the root cause is the same: in workspace mode , the -modfile
flag was not handled correctly.
Update: The following section is not relevant now. Before understanding what mvc is, trying to suppress mvs using the -modfile
flag is a failed attempt.
In the issue report, I suggested blocking the -modfile
flag in workspace mode. But you said in the comments that you need this flag.
The reason for using -modfile
is that if I build a binary for ./src
, even modules present in ./moda
will be included as ./src
Part of the binary file downloaded and loaded, although they should not be included
But according to cmd/go documentation:
-modfile file
In module-aware mode, read (and possibly write) alternate go.mod file instead of a file in the module root directory. A person named "go.mod" must still exist to determine the module root directory, but the directory was not accessed. When -modfile is specified, Also uses an alternate go.sum file: its path is derived from -modfile flag, by trimming the ".mod" extension and appending ".sum".
The-modfile
flag replaces the go.mod
file in the module root directory. But in your example you specified the same file as the one in the module root. So I don't quite understand. Can you update your question to elaborate on this part? Demo is occupied!
The above is the detailed content of go build doesn't work when used with workspace. For more information, please follow other related articles on the PHP Chinese website!