有没有一种方法可以将Go可执行文件分离为多个文件?

时间:2019-01-10 06:21:52

标签: go

我正在运送使用Go编译的几个可执行文件。每个可执行文件本身并不包含很多代码,但是每个文件都使用一个公共库,其中包括日志记录,配置管理,通信层等...

这导致每个可执行文件介于15至20mb之间,有时只需要1000条自己的代码行。

Go中是否有一种方法(当前可用或计划在将来的版本中使用)将应用程序分成几个文件(即Windows中的dll,.so Linux / Mac)?

我知道我可以编译该库,然后将其用作外部二进制文件,但是我将无法获得类型系统和Go编译器优化的好处。我在这里错了吗,有办法吗?

2 个答案:

答案 0 :(得分:5)

简短答案:种类?

听起来您要完成的工作是共享库。

从1.5开始,Go编译器就可以使用-buildmode=c-shared build标志生成共享库:

go build -o helloworld.so -buildmode=c-shared

而且,自Go 1.10起,Windows还额外支持该功能

因此,编译为DLL也是一种方法:

go build -o helloworld.dll -buildmode=c-shared

您将遇到的问题实际上是使用这些库,尤其是以跨操作系统的方式:

在* nix中,您可以使用CGO完成此操作:

package example

// #cgo LDFLAGS: -lfoo
//
// #include <foo.h>
import "C"

func main() {
    C.bar()
}

Windows拥有自己的Wiki(谁感到惊讶?)。

在这方面,我会留下一些想法:

  1. 15至20mb的二进制文件没有什么问题(尽管您应该尝试upx来去除其中的一些脂肪,因为为什么不这样做?),当您重推10到10的演出。这些天空间很便宜。
  2. 写一些可以编译成单个二进制文件的东西,而不管OS是什么,这是Go的最佳优势之一。
  3. CGO_ENABLED=0可以从二进制文件中节省大量空间。保持启用状态(您需要使用这些功能)并不会带来任何好处。
  4. 您正确地假设,由于编译器无法针对所包含的库进行优化,因此最终在较小的用例中您将不会节省太多空间(如果有的话)。

我的最后一点是,然后我将停止向您传教:专注于编写代码。除非您要适合嵌入式设备,否则二进制大小不应该成为您的问题。

祝你好运。

答案 1 :(得分:1)

您要运送的东西是否彼此密切相关?如果是这样,将它们组合成单个可执行文件可能更有意义,该可执行文件将接受命令行上的命令来决定要开始执行的“可执行文件”。

因此,您无需交付“ cmd1”,“ cmd2”和“ cmd3”,而只需交付一个可以通过这种方式调用的程序

$ prog cmd1

$ prog cmd2

$ prog cmd3

您需要做一些额外的工作来解析第一个参数并决定要启动哪个子命令。