0

Let's say that I have a package main which imports two other packages pkg1 and pkg2. pkg1 and pkg2 are not executable packages, they are library packages. Let's say that pkg1 and pkg2 are very large, are maintained on different repositories, and that I would like to compile them separately into two .a binaries. This seems to be possible with

$ go build -i -o ./pkg1/pkg1.a ./pkg1/

When I want to compile my main package, I would like to import those two .a binaries and link them statically as to obtain a single executable file. How can we do that on Windows ? Something like this:

$ go build -link ./pkg1/pkg1.a ./pkg2/pkg2.a -o main.exe ./main/main.go

Note that I don't want to use the C API (by building a .dll and using it with Cgo), but the Go API. Meaning that I want to benefit fully from the capabilities of Go (type safe, garbage collected, etc). I also want to do that on Windows, an OS which is not supported by -buildmode=shared or Go plugins as of today. I don't care if it involves low level commands and black magic.

Now, I know that this is not exactly the "Go way". go build handles the dependencies automatically for us and is very good at it. But I would like to know if it is possible and how to do it nevertheless, as it can be a business requirement when building large binaries, or when shipping compiled libraries to clients for IP reasons.

As a secondary question, If what I want to do is possible, then could the resulting executable file eventually contain multiple instances of the same compiled dependencies (therefore making the executable bigger than necessary)? In that case, is there a way to make sure that the resulting executable would contain exactly one instance of each compiled dependencies?

Victor Deleau
  • 875
  • 5
  • 17
  • 3
    I sounds like you are looking for binary-only packages, which are no longer supported. – JimB Jan 19 '21 at 19:48
  • 1
    "as it can be a business requirement when building large binaries" no because it doesn't matter "or when shipping compiled libraries to clients for IP reasons" you cannot do that: Binary only packages are no longer supported. "eventually contain multiple instances of the same compiled dependencies" No, unwarranted idea. Note that compiling to shared libraries and plugins works and is a major pita. Run go help buildmode. – Volker Jan 19 '21 at 19:50
  • 2
    It's not just "not exactly the Go way". It's wholly unsupported. – Adrian Jan 19 '21 at 20:02
  • @Volker `-buildmode=shared` is not supported on Windows, and so are Go plugins. As for the last citation, why would it be unwarranted? C/C++ use `#ifndef` and `#define` macro directives to avoid that, so how is `go build` doing it? – Victor Deleau Jan 19 '21 at 20:47
  • So no, you cannot do that on Windows, no matter how hard you try. How C/C++ and Go builds and _links_ is different. Your assumptions about duplicated object code are unwarranted. – Volker Jan 19 '21 at 21:04
  • 1
    @VictorDeleau: The go tool will only every link a single instance of a package when building a binary, and unused code is automatically pruned. Note that even if `-buildmode=shared` worked on windows, that is for creating a C shared library, and is not meant to be loaded back into the Go runtime. Support for what you're asking never worked well, and was subsequently dropped. – JimB Jan 19 '21 at 21:04
  • @JimB thanks for your input. I think that what you are talking about is obtained using `-buildmode=c-shared` and not `-buildmode=shared`. C-shared libraries are available [since Go 1.1](https://github.com/golang/go/issues/25155). – Victor Deleau Jan 19 '21 at 21:34
  • 1
    @VictorDeleau: oh sorry, that is what I was thinking of. Yes, users were trying to get around the lack of binary package support with `c-shared`, which does not really work. – JimB Jan 19 '21 at 21:44
  • @JimB good to know that `-buildmode=c-shared` is not working well! – Victor Deleau Jan 19 '21 at 21:47
  • 1
    `c-shared` works well for what it's designed to do. It is not designed to create something to load back into a Go program. – JimB Jan 19 '21 at 21:54
  • Oh ok I understand now. – Victor Deleau Jan 19 '21 at 22:08

0 Answers0