GO編譯器PDF
Ⅰ Go 語言到底適合干什麼
Go語言主要用作伺服器端開發,其定位是用來開發「大型軟體」的,適合於需要很多程序員一起開發,並且開發周期較長的大型軟體和支持雲計算的網路服務。
Go語言融合了傳統編譯型語言的高效性和腳本語言的易用性和富於表達性,不僅提高了項目的開發速度,而且後期維護起來也非常輕松。
編譯器
當前有兩個Go編譯器分支,分別為官方編譯器gc和gccgo。官方編譯器在初期使用C寫成,後用Go重寫從而實現自舉。Gccgo是一個使用標准GCC作為後端的Go編譯器。
官方編譯器支持跨平台編譯(但不支持CGO),允許將源代碼編譯為可在目標系統、架構上執行的二進制文件。
Ⅱ Go 編譯器介紹
在探討 Go 編譯器的構造及其核心流程時,我們首先需要理解其功能及邏輯結構。Go 編譯器在邏輯上主要被分為四個階段,每個階段都負責不同的任務,具體包括解析、類型檢查和 AST 變換、通用 SSA 轉換以及生成機器碼。
第一階段:解析。此階段首先對源代碼進行標記化和解析,形成語法樹。標記化過程識別出代碼中的一系列預定義元素,如標識符、關鍵字、分隔符、操作符等,並為每個源文件構建精確的表示。語法樹包含位置信息,以輔助錯誤報告和調試信息生成。
第二階段:類型檢查和 AST 變換。此階段通過轉換語法樹為編譯器的 AST 表示法,執行類型檢查。類型檢查包括解析名字和類型推斷,確定每個對象的標識符和類型,以及執行特定的額外檢查,如聲明但未使用的變數檢查以及函數是否會終止。此外,進行特定變換,如字元串加法的分離、死代碼消除、函數內聯和逃逸分析等。
第三階段:通用 SSA 轉換。在這一階段,編譯器將 AST 轉換為靜態單賦值(SSA)形式,這是一種低級中間表示法。SSA 具有特定屬性,便於優化並最終生成機器碼。內置函數在此階段進行處理,替換為優化的代碼。特定節點被轉化為更簡單的組件,以供後續編譯階段使用。通用的機器無關規則和編譯環節執行,包括死代碼消除、不必要的空值檢查移除等。
第四階段:生成機器碼。此階段涉及將通用變數轉換為特定機器碼形式,針對目標體系結構進行優化。在 SSA 被轉換並針對目標架構具體化後,執行最終的代碼優化,包括死代碼消除、變數移動、寄存器分配等。堆棧布局和指針活性分析也在此階段完成。在 SSA 生成階段結束時,Go 函數已轉換為一系列 obj.Prog 指令,傳遞給匯編程序進一步轉換為機器碼,並輸出目標文件。
深入理解 SSA 包的工作方式及其環節和規則,可以參考 cmd/compile/internal/ssa/README.md 文件。這些資源提供了詳細信息和深入研究的途徑。
Ⅲ go語言是編譯型還是解釋型
Go語言是編譯型語言。
首先,理解編譯型和解釋型語言的差異是關鍵。編譯型語言會將源代碼轉換為機器代碼,這是一組可以直接由計算機執行的低級指令。這個過程通常發生在程序運行之前,因此編譯型語言通常具有較高的執行速度。相反,解釋型語言在程序運行時,會逐行讀取源代碼並將其轉換為機器代碼執行。由於這個過程在運行時進行,解釋型語言的執行速度通常比編譯型語言慢。
Go語言被設計為編譯型語言。當我們使用Go編譯器(如gc)編譯Go程序時,它會將Go源代碼(.go文件)轉換為二進制可執行文件。這個過程通常發生在程序運行之前。這意味著,一旦編譯完成,生成的二進制文件可以直接在計算機上運行,無需任何中間的解釋或轉換過程。
舉個例子,如果我們有一個簡單的Go程序,如下所示:
go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
使用Go編譯器,我們可以將這個源代碼文件編譯為一個可執行文件。在命令行中,我們可以使用以下命令來完成這個過程:
bash
go build -o hello hello.go
上述命令會生成一個名為“hello”的可執行文件。這個文件是機器代碼,可以直接在計算機上運行。當我們運行這個文件時,它會直接輸出“Hello, World!”,無需任何中間的解釋或轉換過程。
總結來說,Go語言是編譯型語言,它將源代碼預先轉換為機器代碼,這使得Go程序具有較高的執行速度。
Ⅳ Go 是怎麼使用 Go 來編譯自身的
是Go語言嗎?
Go 編譯過程 九個步驟
第一步. all.bash
%cd$GOROOT/src
%./all.bash
第一步 all.bash只是調用了另外兩個 shell 腳本:make.bash和run.bash。若使用 Windows 或 Plan 9,其過程也基本類似,只是腳本分別以 .bat 或 .rc 結尾。在文章的其他部分,請用適當的操作系統對應的擴展來補全命令。
第二步. make.bash
../make.bash--no-banner
make.bash 作為 all.bash 內容的一部分,如果它退出也會中斷構建過程
第三步. cmd/dist
python">gcc-O2-Wall-Werror-ggdb-ocmd/dist/dist-Icmd/distcmd/dist/*.c
當健全檢查完成後,make.bash 開始編譯cmd/dist。
第四步. go_bootstrap
現在 go_bootstrap 已經構建完成,make.bash 的最後一步是使用 go_bootstrap 編譯完整的 Go 標准庫,包括一個完整的 go 工具用以替換。
echo"#$GOOS/$GOARCH."
"$GOTOOLDIR"/go_bootstrapinstall-gcflags"$GO_GCFLAGS"
-ldflags"$GO_LDFLAGS"-vstd
第五步. run.bash
現在 make.bash 已經完成,回到 all.bash 的執行,這會調用 run.bash。run.bash 的任務是編譯和測試標准庫、運行時以及語言測試集。
bashrun.bash--no-rebuild
由於 make.bash 和 run.bash 都會調用 go install -a std,因此需要使用 –no-rebuild 標志來避免重復前面的步驟,–no-rebuild 跳過了第二個 go install。
#allowall.bashtoavoiddouble-buildofeverythingrebuild=trueif["$1"="--no-rebuild"];thenshiftelseecho'#Buildingpackagesandcommands.'timegoinstall-a-vstdechofi
第六步. go test -a std
php">echo'#Testingpackages.'
timegoteststd-short-timeout=$(expr120*$timeout_scale)s
echo
接下來 run.bash 會在標准庫里所有的包上來運行用 testing 包編寫的單元測試。由於 $GOPATH 和 $GOROOT 中有著相同的命名空間,所以不能直接使用 go test … 否則 $GOPATH 中的每個包也會被逐一測試,因此創建了一個用於標准庫中的包的別名:std。由於一些測試需要比較長的時間,且會消耗大量內存,因此用 -short 標志對一些測試進行了過濾。
第七步. runtime 和 cgo 測試
run.bash 接下來的部分會運行平台對 cgo 支持的測試,執行一些性能測試,並且編譯一些伴隨 Go 發行版一起的雜項程序。隨著時間的流逝,這些雜項程序的清單會越來越長,那麼它們也就會不可避免的被從編譯過程中悄悄剝離出去。
第八步. go run test
(xcd../test
unsetGOMAXPROCS
timegorunrun.go
)||exit$?
run.bash 的倒數第二步會調用在 $GOROOT 下的 test 目錄里的編譯器和運行時的測試。他們是對於編譯器和運行時自身的,較為低級細節的測試。會執行語言規格測試,test/bugs 和 test/fixedbugs 子目錄保存有那些已經被發現並被修復的問題的獨立的測試。驅動測試的是一個小 Go 程序 $GOROOT/test/run.go,會執行 test 目錄里的每個 .go 文件。一些 .go 文件的首行包含了指導 run.go 對結果作出判斷的指令,例如,程序將會失敗,或提供一個確定的輸出隊列。
第九步. go tool api
echo'#CheckingAPIcompatibility.'
gotoolapi-c$GOROOT/api/go1.txt,$GOROOT/api/go1.1.txt
-next$GOROOT/api/next.txt-except$GOROOT/api/except.txt
run.bash 的最後一步調用了 api 工具。