【问题标题】:go: Why do I need the pkg directory if I cannot delete the source files in src?go: 如果我无法删除 src 中的源文件,为什么我需要 pkg 目录?
【发布时间】:2018-02-05 00:05:29
【问题描述】:

我写了一个函数(不是!main)并提示go install。该命令在我的 pkg-directory 中生成了一个路径和一个包。我通过在 main 函数 中使用它来测试该函数,生成了 .exe,一切正常。 之后我想看看我对go中的packages的概念理解有没有正确,把src-directory中函数的源文件删掉,把主.exe。我确实没有删除了我的 pkg-directory 中的包文件。然后我再次尝试go install main .exe,但没有成功:“找不到包”。我显然误解了整个概念,因为我认为我可以使用 pkg 中的包,而无需 src 中的源文件。如果我的结论是正确的,为什么我需要“pkg”目录呢?


For more explanation take a look at this picture please:

/bin 中是主函数“hello”的二进制代码。这个主函数还包含“stringutil”包的“reverse”函数。

通过生成“hello.exe”,Go 还将包“stringutil”生成到 pkg 中。

我的问题是:我是否应该无法删除 src 中的“reverse.go”,并且仍然可以使用相同的功能,因为它已经放入了 pkg?


现在他们已经重写了编译器,AST 的工作方式是这样的吗?它在解析“导入”时检查 GOPATH/src/**/.go,然后当链接器去构建最终的二进制文件时,它会去检查 pkg。因此,由于源代码树不完整,编译器在尝试将 ast 提供给汇编器时首先出错。

非常感谢!!!

【问题讨论】:

  • 当然你可以删除源文件并只使用 pkg 中的 .a 文件:你所要做的就是手动调用 Go 编译器和链接器,而不是通过 go tool。您遇到的是 go 工具的工作方式,与 Go 作为一种语言或“包的工作方式”无关。

标签: go


【解决方案1】:

确实 pkg 目录通常用作缓存目录,但也可以在没有可用源代码的情况下使用包,具有名为 binary only packagesAFAIK 的功能,它是从 Go 1.7 开始实现的。 但是,这种方法有一个警告:用于构建包的编译器版本和“使用”包生成新库/可执行文件的编译器版本必须匹配。此外,文件必须与要构建的操作系统/架构对匹配。如果你想要交叉编译,你需要将你的包分发到你想要构建的每一对操作系统/架构。

This 项目有上述功能的演示。

我希望我的解释足够详细:)

【讨论】:

  • official docs 中提到了该功能,但并不像人们想要的那样详细
【解决方案2】:

pkg 目录只是用于编译的本地缓存,它不是您可以依赖的东西,它不会替换 .go 文件,它不是静态库目录,而是临时构建产品目录。它加快了编译速度,因此您不需要 pkg 目录,但如果它为空,编译可能会更慢,并且它是供编译器使用的,而不是您的。

正如您所发现的,您确实需要 src 目录。

要将静态库链接到您的项目,您可以复制该 .a 文件并使用 ldflags 进行链接,但随后您将失去所有好处,例如交叉编译和拥有应用程序的整个源代码,因此与 c 不同的是例如人们通常不会这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    相关资源
    最近更新 更多