Rumah > Artikel > pembangunan bahagian belakang > Pembenaman maklumat dalam perduaan Go 1.18
Mungkin semua orang pernah mendengar ciri-ciri di atas. Selepas membaca nota keluaran, saya melihat ciri baharu yang mungkin tidak disedari oleh semua orang: pembenaman maklumat fail binari.
Sebab mengapa kami memberi perhatian kepada perkara ini ialah kami baru sahaja membincangkan isu ini dalam artikel Penyelesaian pengurusan nombor versi projek Go yang berbeza minggu lepas, dan rasanya ia disambungkan dengan yang rasmi Perfect kombo.
Dalam Go 1.18, melalui arahan go build build, kita boleh membenamkan maklumat bina ke dalam fail binari.
Seterusnya, mari kita rasainya secara intuitif melalui contoh.
Pertama, pastikan versi Go 1.18 dipasang melalui arahan versi go.
$ go version go version go1.18 darwin/amd64
Kemudian, mulakan persekitaran projek
$ mkdir versionDemo $ cd versionDemo $ go mod init example/version $ touch main.go
Di main.go, tulis logik pencetakan yang mudah
package main import ( "fmt" ) func main() { fmt.Println("HELLO GOPHER") }
Pada ketika ini, kami menyusun dan mendapatkan fail binari
A mendapat fail binari fail binari, Anda boleh mendapatkan beberapa maklumat meta apabila menyusun fail melalui arahan berikut
$ 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 二进制文件是否是预期程序,代码提交的发版部署是否有误等。
Atas ialah kandungan terperinci Pembenaman maklumat dalam perduaan Go 1.18. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!