0

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

ArigatoManga
  • 594
  • 5
  • 23
  • Have you tried `go build -o test-binary1 -modfile ./go.mod .`? – Zeke Lu May 04 '23 at 15:03
  • that wouldn't work right because my code is in ./src not in . – ArigatoManga May 04 '23 at 15:14
  • Does `src` have its own `go.mod`? Why are you specifying `-modfile`? – JimB May 04 '23 at 15:15
  • no src does not have a `go.mod` i tried that way but even that did not work. 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 – ArigatoManga May 04 '23 at 15:20
  • I think maybe you are confusing the tool by having a workspace directory directly inside your module. Try moving that up a level and building the packages by name like in the [docs](https://go.dev/doc/tutorial/workspaces)? – JimB May 04 '23 at 15:25

1 Answers1

2

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!

Zeke Lu
  • 6,349
  • 1
  • 17
  • 23
  • edited the question and added example source – ArigatoManga May 08 '23 at 12:40
  • hmm, we need to understand what exactly is `the submodule imports getting added to mainmodule executable`. Can you share the output of `go build -n`? (It's ok to remove confidential from the output). BTW, have you compare the generated binaries? – Zeke Lu May 08 '23 at 12:53
  • Does the mainmodule import any packages from the submodule? – Zeke Lu May 08 '23 at 12:55
  • main does not import any modules from submodule both are independent – ArigatoManga May 08 '23 at 13:02
  • Good! That makes it easy to narrow down the issue. Can you build the mainmodule in the work space first, and then build again after deleting `go.work` and `go.work.sum` (the purpose is to build it without the workspace)? And then compare the binaries to see if there is a big difference in the size. – Zeke Lu May 08 '23 at 13:11
  • yes there is a difference of 50-60KB – ArigatoManga May 08 '23 at 13:19
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/253536/discussion-between-arigatomanga-and-zeke-lu). – ArigatoManga May 08 '23 at 13:20