This is a creation in Article, where the information may have evolved or changed.
Before Dave Cheney has explained to us how go is compiled with go. Here, he continues to explain to you how the Go Build command works (in the original).
———— Translation Divider Line ————
How does the Go build command work?
Taking the standard library of go as an example, this paper introduces the working principle of go compiling process.
GC Tool Chain
This article focuses on the GC tool chain. The name of the GC Toolchain is derived from the Go front-end compiler CMD/GC, which is primarily intended to be differentiated from the Gccgo toolchain. When people talk about Go compilers, they mostly refer to the GC toolchain. This article does not focus on the GCCGO tool chain.
The GC toolchain is stripped directly from the tool chain of Plan 9. The toolchain consists of a Go compiler, a C compiler, a assembler, and a linker. These tools can be found in the src/cmd/subdirectory of the Go code, including the front end shared with all implementations, and the specific back end under different processor architectures. The back end is identified with a specific letter, which is also a tradition of Plan 9. Commands include:
5g, 6g, and 8g are the corresponding compilers for the. Go file for arm, AMD64, and 386.
5c, 6c, and 8c are the compilers for. c files that correspond to arm, AMD64, and 386;
5a, 6a and 8a are the compilers for. s files for arm, AMD64, and 386;
5l, 6l, and 8l are the linker for the files generated by the above commands, as well as for arm, AMD64 and 386.
It is important to note that each command can be compiled on any supported platform, which is a reflection of the cross-compilation capability of Go. You can learn more about cross-compiling in this article.
Building Packages
Build a go package with at least two steps, compile the. go file, and then package the compilation results. Given that Crypto/hmac is small, there is only one source file and a test file, so use it for illustrative purposes. Use the-X option to tell go build to print out every step it takes
% go build-x crypto/hmacwork=/tmp/go-build249279931mkdir-p $WORK/crypto/hmac/_obj/mkdir-p $WORK/crypto/cd/home/dfc/ Go/src/pkg/crypto/hmac/home/dfc/go/pkg/tool/linux_arm/5g-o $WORK/crypto/hmac/_obj/_go_.5-p Crypto/hmac-complete- D _/home/dfc/go/src/pkg/crypto/hmac-i $WORK./hmac.go/home/dfc/go/pkg/tool/linux_arm/pack GrcP $WORK $WORK/crypto/ HMAC.A $WORK/crypto/hmac/_obj/_go_.5
Understand these steps individually
Work=/tmp/go-build249279931mkdir-p $WORK/crypto/hmac/_obj/mkdir-p $WORK/crypto/
Go build Creates a temp directory/tmp/go-build249279931 and populates some of the skeleton subdirectories for saving the compiled results. The second mkdir may be superfluous, and the issue 6538来 has been created to track this issue.
Cd/home/dfc/go/src/pkg/crypto/hmac/home/dfc/go/pkg/tool/linux_arm/5g-o $WORK/crypto/hmac/_obj/_go_.5-p crypto/ Hmac-complete-d _/home/dfc/go/src/pkg/crypto/hmac-i $WORK./hmac.go
The Go tool switches the CRYPTO/HMAC source directory and calls the schema's go compiler, which in this case is 5g. There is actually no CD, and when 5g executes,/home/dfc/go/src/pkg/crypto/hmac is passed as a parameter of Exec.Command.Dir. This means that in order to make the command line more streamlined, the. Go source file can use the relative path corresponding to its source code directory.
The compiler generates a unique temporary file $WORK/crypto/hmac/_obj/_go_.5 will be used in the last step.
/home/dfc/go/pkg/tool/linux_arm/pack GRCP $WORK $WORK/crypto/hmac.a $WORK/crypto/hmac/_obj/_go_.5
The final step is to package the target file to the archive file that will be used by the linker and compiler. A.
As the go build is called on the package, the results in the $WORK are deleted after the compilation is complete. If you call go install-x it will output an additional two lines
Mkdir-p/HOME/DFC/GO/PKG/LINUX_ARM/CRYPTO/CP $WORK/CRYPTO/HMAC.A/HOME/DFC/GO/PKG/LINUX_ARM/CRYPTO/HMAC.A
This demonstrates the difference between go build and install, build build, install and installation for other builds.
Build more complex packages
You may be thinking about the packaging steps in the previous example. The compiler and linker here only accept a single file as the content of the package, and if it contains multiple target files, it must be packaged into a single. A archive file before using them.
CGO is a common example of producing more than one intermediate target file, but it is too complicated for this article, as an alternative example of the case where the. S assembly file is included, such as CRYPTO/MD5.
% go build-x crypto/md5work=/tmp/go-build870993883mkdir-p $WORK/crypto/md5/_obj/mkdir-p $WORK/crypto/cd/home/dfc/go /src/pkg/crypto/md5/home/dfc/go/pkg/tool/linux_amd64/6g-o $WORK/crypto/md5/_obj/_go_.6-p crypto/md5-d _/home/dfc/ Go/src/pkg/crypto/md5-i $WORK./md5.go./md5block_decl.go/home/dfc/go/pkg/tool/linux_amd64/6a-i $WORK/crypto/md5/_ obj/-o $WORK/crypto/md5/_obj/md5block_amd64.6-d goos_linux-d goarch_amd64./md5block_amd64.s/home/dfc/go/pkg/tool/ Linux_amd64/pack GRCP $WORK $WORK/crypto/md5.a $WORK/crypto/md5/_obj/_go_.6 $WORK/crypto/md5/_obj/md5block_amd64.6
This example executes on the LINUX/AMD64 host, 6g is tuned to compile two. Go files: Md5.go and Md5block_decl.go. This later contains declarations of functions implemented with assemblies.
The 6a is then tuned to assemble the MD5BLOCK_AMD64.S. The logic of choosing which. s to compile is explained in my previous article on conditional compilation.
Finally call Pack to package Go's target file _go_.6, and assemble the target file md5block_amd64.6 to a single archive file.
Build command
A Go command is a package named Main. The main package, or the command is compiled in the same way as the other packages, but they are internally subjected to a number of additional steps to link to the final executable file. Let's take a look at the process through CMD/GOFMT.
% go build-x cmd/gofmtwork=/tmp/go-build979246884mkdir-p $WORK/cmd/gofmt/_obj/mkdir-p $WORK/CMD/GOFMT/_OBJ/EXE/CD/ Home/dfc/go/src/cmd/gofmt/home/dfc/go/pkg/tool/linux_amd64/6g-o $WORK/cmd/gofmt/_obj/_go_.6-p Cmd/gofmt-complete -D _/home/dfc/go/src/cmd/gofmt-i $WORK./doc.go./gofmt.go./rewrite.go./simplify.go/home/dfc/go/pkg/tool/linux_ Amd64/pack GRCP $WORK $WORK/cmd/gofmt.a $WORK/cmd/gofmt/_obj/_go_.6cd./home/dfc/go/pkg/tool/linux_amd64/6l-o $WORK/ Cmd/gofmt/_obj/exe/a.out-l $WORK $WORK/CMD/GOFMT.ACP $WORK/cmd/gofmt/_obj/exe/a.out gofmt
The previous six lines should already be familiar, and the main package will be compiled and packaged like any other Go package.
The difference is in the second-to-last line, which invokes the linker to generate a binary executable file.
/home/dfc/go/pkg/tool/linux_amd64/6l-o $WORK/cmd/gofmt/_obj/exe/a.out-l $WORK $WORK/cmd/gofmt.a
The last line copies and renames the compiled binary file to its final location and name. If you use go install, the binary is also copied to the $GOPATH/bin ($GOBIN if $GOBIN is set).
Historical reasons
If you go back to a time long enough to go back to the Go tool and go back to the makefiles era, you can find the core of the go compilation process. This example comes from Release.r60 's documentation
$ cat >hello.go <<eofpackage mainimport "FMT" Func Main () { fmt. Printf ("Hello, world\n")}eof$ 6g hello.go$ 6l hello.6$./6.outhello, World
That being the case, 6g compiled the. go file to the. 6 destination file, the 6l link destination file, and the FMT (and runtime) package to generate the binary file 6.out.
Conclusion
In this article, we discuss how go build works and understand the different ways that go install does with compilation results.
Now that you know how the go build works, and how to show the compilation process through-X, you can try passing the identity to go test and observing its results.
Also, if you already have GCCGO installed in your system, you can pass-compiler Gccgo to go build and use-X to see how the Go code compiles with this compiler.