Heim > Artikel > Backend-Entwicklung > Einbettung von Informationen in Go 1.18-Binärdateien
Vielleicht hat jeder von den oben genannten Eigenschaften gehört. Nachdem ich die Versionshinweise gelesen hatte, fiel mir eine neue Funktion auf, die vielleicht nicht jedem aufgefallen ist: die Einbettung von Binärdateiinformationen.
Der Grund, warum wir diesem Punkt Aufmerksamkeit schenken, ist, dass wir dieses Problem erst letzte Woche im Artikel Eine andere Versionsnummernverwaltungslösung für Go-Projekte besprochen haben und es sich anfühlt, als ob es mit der offiziellen Version von Perfect zusammenhängt Combo.
In Go 1.18 können wir mit dem Befehl „go build build“ Build-Informationen in die Binärdatei einbetten.
Als nächstes wollen wir es anhand von Beispielen intuitiv spüren.
Stellen Sie zunächst sicher, dass die Version Go 1.18 über den Befehl go version installiert ist.
$ go version go version go1.18 darwin/amd64
Dann initialisieren Sie die Projektumgebung
$ mkdir versionDemo $ cd versionDemo $ go mod init example/version $ touch main.go
Schreiben Sie in main.go eine einfache Drucklogik
package main import ( "fmt" ) func main() { fmt.Println("HELLO GOPHER") }
An diesem Punkt kompilieren wir die Binärdatei und erhalten sie
$ go build -o main1.18 example/version
Nach Erhalt der Binärdatei. Sie können beim Kompilieren der Datei mit dem folgenden Befehl einige Metainformationen abrufen
$ go version -m main1.18 main1.18: go1.18 path example/version mod example/version (devel) build -compiler=gc build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=darwin build GOAMD64=v1
可以看到,通过 <span style="font-size: 15px;">go version -m binaries</span>
,我们可以获取到二进制文件的各项构建信息。
当然,如果在构建过程中,为二进制文件指定了 -tags 等,我们同样能够以上的方式获取。
$ go build -tags version1.1 --ldflags="-X 'main.s=sss'" -o main1.18more example/version $ go version -m main1.18more main1.18more: go1.18 path example/version mod example/version (devel) build -compiler=gc build -ldflags="-X 'main.s=sss'" build -tags=version1.1 build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=darwin build GOAMD64=v1
正如在一个不一样的 Go 项目版本号管理方案一文中探讨过的一样,版本信息不应该仅包含 Go 本身的信息,还应该包含 VCS 信息,例如 Git、Mercurial、Fossil 和 Bazaar。
在 Go 1.18,通过 go help build 命令,可以看到多了 -buildvcs 参数,它默认是打开的。
$ go help build ... -buildvcs Whether to stamp binaries with version control information. By default, version control information is stamped into a binary if the main package and the main module containing it are in the repository containing the current directory (if there is a repository). Use -buildvcs=false to omit version control information. ...
在上述项目中,我们添加 Git 版本控制。
$ git init $ go build -o mainwithgit example/version $ go version -m mainwithgit mainwithgit: go1.18 path example/version mod example/version (devel) build -compiler=gc build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=darwin build GOAMD64=v1 build vcs=git build vcs.modified=true
此时,输出信息中多出了两列关于 vcs 的信息。接下来,我们将仓库内文件保存并提交。
$ git add go.mod main.go $ git commit -m 'feat: this is a commit message' $ go build -o mainwithgit example/version $ go version -m mainwithgit $ go version -m mainwithgit mainwithgit: go1.18 path example/version mod example/version (devel) build -compiler=gc build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=darwin build GOAMD64=v1 build vcs=git build vcs.revision=f28c77dfcfcfb5289fae9318d3ab3e487b8a3b37 build vcs.time=2022-03-20T14:26:24Z build vcs.modified=true
二进制文件中记录了更详细 vcs 信息,包括 git 版本号,提交时间等。
出于某些原因,有时我们并不想二进制中包含这些 vcs 信息,这时,在构建时指定 <span style="font-size: 15px;">-buildvcs=false</span>
即可。
在上面的场景中,我们都是通过执行 <span style="font-size: 15px;">go version -m binaries</span>
命令查看二进制文件的嵌入信息的。但是,在能拿到二进制文件的场景下,并不总是存在 Go 环境,例如没有 Go 环境的远程服务器。这样的场景中,如何查看它的嵌入信息呢?
这时,可以通过 <span style="font-size: 15px;">runtime/debug.ReadBuildInfo</span>
获取。例如,我们将上述例子中的 main.go 的内容更改如下
package main import ( "fmt" "runtime/debug" ) func main() { info, _ := debug.ReadBuildInfo() fmt.Println("=========== build info ===========") fmt.Println(info) }
同样可得到构建信息如下
=========== build info =========== go go1.18 path workspace/example/versionDemo mod workspace/example/versionDemo (devel) build -compiler=gc build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=darwin build GOAMD64=v1 build vcs=git build vcs.revision=b3f9cd7b83d4e624be942365728d676dfdca6a3e build vcs.time=2022-03-20T14:10:44Z build vcs.modified=true
因此,为了解决没有 Go 环境的远程服务器不能查看嵌入信息的情况。我们不妨利用 <span style="font-size: 15px;">runtime/debug.ReadBuildInfo</span>
函数,将其封装为一个接口,访问该接口即可获取当前二进制文件的嵌入信息。
其实在 1.18 之前的版本中,Go 二进制文件就包括了少许的嵌入信息。例如同样是上文中的项目,我们通过 1.16 构建二进制文件,读取它的嵌入信息,其仅包括了 path 与 mod 信息。
$ go1.16.4 build -o main1.16 example/version $ go1.16.4 version -m main1.16 main1.16: go1.16.4 path example/version mod example/version (devel)
在 1.18 中,通过丰富二进制文件的嵌入信息,能够让我们更好地了解到当前程序。例如利用 vcs 信息可以判断从三方获取的 Go 二进制文件是否是预期程序,代码提交的发版部署是否有误等。
Das obige ist der detaillierte Inhalt vonEinbettung von Informationen in Go 1.18-Binärdateien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!