我试图了解第三方依赖项的源代码是如何编译成我的Go二进制文件的。我是在一个Docker容器中构建的,所以我可以在不受其他构建干扰的情况下精确地看到为我的构建获取的内容。
在我的go build完成之后,我看到了go/pkg/mod/$module@$version目录下几个依赖项的源代码文件。模块缓存文档告诉我,这些目录包含“提取的模块.zip文件的内容,这作为下载模块的模块根目录。”我最好的猜测是,为这些依赖项提取的源代码的存在表明,“是的,这些依赖项肯定被编译到二进制文件中。”
我还看到更多的依赖项被拖到go/pkg/mod/cache/download/$module目录中。模块缓存文档告诉我,这个目录包含“从模块代理下载的文件和从版本控制系统派生的文件”,我不完全理解。据我所见,这些文件不包含任何提取的源代码,尽管我假设有几个.zip文件包含源代码。在大多数情况下,这些文件似乎是.mod文件,只包含表示某种依赖关系图的文本。
我的问题是:如果第三方依赖项在go/pkg/mod/cache/download 下有模块文件,但在 go/pkg/mod/$module@$version**,下没有源代码,这是否意味着依赖项的代码没有编译到Go二进制文件中?**
我不明白Go构建为什么会吸引所有这些模块文件,但只提取了一些第三方模块的源代码。也许可以先发制人地分析并提取从我的第一方代码导入的模块中引用的完整传递模块集的模块信息,但也许这些模块中的许多模块最终并不是我的二进制代码编译+构建过程所需要的,因此不会被提取。如果这不是真的,并且我的问题的答案是否定的,那么我不明白我的二进制文件如何或者为什么可以在这些依赖项中链接,而不需要go build获取它们的源代码。
发布于 2021-10-29 05:50:49
正如"编译和安装软件包和依赖项“中提到的
编译后的包将自动缓存。
和模块包括:
在使用模块时,GOPATH不再用于解析导入。 但是,它仍然用于存储下载的源代码(在
GOPATH/pkg/mod中)和编译的命令(在GOPATH/bin中)。
因此,如果您在pkg/mod中看到不在pkg/mod/cache中的源代码,请尝试使用go mod tidy
添加缺失并删除未使用的模块
在那里,源(pkg/mod)和编译模块(pkg/mod/cache)之间应该有相同的模块。
发布于 2021-10-29 07:05:32
根据任择议定书的评论
出于遵从性的原因,我需要确切地知道二进制文件中包含了什么。
我建议一种完全不同的方法:将二进制中包含的符号列表转储,然后将其与所需的任何信息相关联。
命令
go tool nm -type /path/to/the/executable/image/file将转储函数的符号--函数的名称--其代码来自标准库包、第三方和/或终端包和内部包,编译并链接到二进制文件中,并打印到其标准输出流中的一行序列。
address type name然后可以以编程方式处理。
您可能使用的另一种方法是使用带有各种标志的go list查询程序的源代码,这些包和/或模块在构建时将使用:描述源代码的完整依赖关系图的任何命令输出都是go build在构建时使用的--只要源代码在这些调用之间不发生更改。
还有一种可能是使用go build -x构建程序,保存它在标准错误流上生成的调试跟踪,并解析它以获得在构建过程中报告的命令的确切模块名称。
https://stackoverflow.com/questions/69759474
复制相似问题