命令 go env 用於打印 Go 語言的環境信息。其中的一些信息我們在之前已經多次提及,但是卻沒有進行詳細的說明。在本小節,我們會對這些信息進行深入介紹。我們先來看一看 go env 命令情況下都會打印出哪些 Go 語言通用環境信息。
表0-25 go env 命令可打印出的 Go 語言通用環境信息
名稱 | 說明 |
---|---|
CGO_ENABLED | 指明cgo工具是否可用的標識。 |
GOARCH | 程序構建環境的目標計算架構。 |
GOBIN | 存放可執行文件的目錄的絕對路徑。 |
GOCHAR | 程序構建環境的目標計算架構的單字符標識。 |
GOEXE | 可執行文件的后綴。 |
GOHOSTARCH | 程序運行環境的目標計算架構。 |
GOOS | 程序構建環境的目標操作系統。 |
GOHOSTOS | 程序運行環境的目標操作系統。 |
GOPATH | 工作區目錄的絕對路徑。 |
GORACE | 用於數據競爭檢測的相關選項。 |
GOROOT | Go語言的安裝目錄的絕對路徑。 |
GOTOOLDIR | Go工具目錄的絕對路徑。 |
下面我們對這些環境信息進行逐一說明。
CGO_ENABLED
通過上一小節的介紹,相信讀者對 cgo 工具已經很熟悉了。我們提到過,標准 go 命令可以自動的使用 cgo 工具對導入了代碼包 C 的代碼包和源碼文件進行處理。這里所說的“自動”並不是絕對的。因為當環境變量 CGO_ENABLED 被設置為 0 時,標准 go 命令就不能處理導入了代碼包 C 的代碼包和源碼文件了。請看下面的示例:
hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=0 hc@ubt:~/golang/goc2p/src/basic/cgo$ go build -x WORK=/tmp/go-build775234613
我們臨時把環境變量 CGO_ENABLED 的值設置為 0,然后執行 go build 命令並加入了標記 -x。標記 -x 會讓命令程序將運行期間所有實際執行的命令都打印到標准輸出。但是,在執行命令之后沒有任何命令被打印出來。這說明對代碼包 basic/cgo 的構建操作並沒有被執行。這是因為,構建這個代碼包需要用到 cgo 工具,但 cgo 工具已經被禁用了。下面,我們再來運行調用了代碼包 basic/cgo 中函數的命令源碼文件 cgo_demo.go。也就是說,命令源碼文件 cgo_demo.go 間接的導入了代碼包 C。還記得嗎?這個命令源碼文件被存放在 goc2p 項目的代碼包 basic/cgo 中。示例如下:
hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=0 hc@ubt:~/golang/goc2p/src/basic/cgo$ go run -work cgo_demo.go WORK=/tmp/go-build856581210 # command-line-arguments ./cgo_demo.go:4: can't find import: "basic/cgo/lib"
在上面的示例中,我們在執行 go run 命令時加入了兩個標記—— -a 和 -work。標記 -a 會使命令程序強行重新構建所有的代碼包(包括涉及到的標准庫),即使它們已經是最新的了。標記 -work 會使命令程序將臨時工作目錄的絕對路徑打印到標准輸出。命令程序輸出的錯誤信息顯示,命令程序沒有找到代碼包 basic/cgo。其原因是由於代碼包 basic/cgo 無法被構建。所以,命令程序在臨時工作目錄和工作區中都找不到代碼包 basic/cgo 對應的歸檔文件 cgo.a。如果我們使用命令 ll /tmp/go-build856581210 查看臨時工作目錄,也找不到名為 basic 的目錄。
不過,如果我們在環境變量 CGO_ENABLED 的值為 1 的情況下生成代碼包 basic/cgo 對應的歸檔文件 cgo.a,那么無論我們之后怎樣改變環境變量 CGO_ENABLED 的值也都可以正確的運行命令源碼文件 cgo_demo.go。即使我們在執行 go run 命令時加入標記 -a 也是如此。因為命令程序依然可以在工作區中找到之前在我們執行 go install 命令時生成的歸檔文件 cgo.a。示例如下:
hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=1 hc@ubt:~/golang/goc2p/src/basic/cgo$ go install ../basic/cgo hc@ubt:~/golang/goc2p/src/basic/cgo$ export CGO_ENABLED=0 hc@ubt:~/golang/goc2p/src/basic/cgo$ go run -a -work cgo_demo.go WORK=/tmp/go-build130612063 The square root of 2.330000 is 1.526434. ABC CFunction1() is called. GoFunction1() is called.
由此可知,只要我們事先成功安裝了引用了代碼包 C 的代碼包,即生成了對應的代碼包歸檔文件,即使 cgo 工具在之后被禁用,也不會影響到其它 Go 語言代碼對該代碼包的使用。當然,命令程序首先會到臨時工作目錄中尋找需要的代碼包歸檔文件。
關於 cgo 工具還有一點需要特別注意,即:當存在交叉編譯的情況時,cgo 工具一定是不可用的。在標准 go 命令的上下文環境中,交叉編譯意味着程序構建環境的目標計算架構的標識與程序運行環境的目標計算架構的標識不同,或者程序構建環境的目標操作系統的標識與程序運行環境的目標操作系統的標識不同。在這里,我們可以粗略認為交叉編譯就是在當前的計算架構和操作系統下編譯和構建 Go 語言代碼並生成針對於其他計算架構或/和操作系統的編譯結果文件和可執行文件。
GOARCH
GOARCH 的值的含義是程序構建環境的目標計算架構的標識,也就是程序在構建或安裝時所對應的計算架構的名稱。在默認情況下,它會與程序運行環境的目標計算架構一致。即它的值會與 GOHOSTARCH 的值是相同。但如果我們顯式的設置了環境變量 GOARCH,則它的值就會是這個環境變量的值。
GOBIN
GOBIN 的值為存放可執行文件的目錄的絕對路徑。它的值來自環境變量 GOBIN。在我們使用 go tool install 命令安裝命令源碼文件時生成的可執行文件會存放於這個目錄中。
GOCHAR
GOCHAR 的值是程序構建環境的目標計算架構的單字符標識。它的值會根據 GOARCH 的值來設置。當 GOARCH 的值為 386 時,GOCHAR 的值就是 8。當 GOARCH 的值為 amd64 時 GOCHAR 的值就是 6。而 GOCHAR 的值 5 與 GOARCH 的值 arm 相對應。
GOCHAR 主要有兩個用途,列舉如下:
-
Go 語言官方的平台相關的工具的名稱會以它的值為前綴。的名稱會以 GOCHAR 的值為前綴。比如,在 amd64 計算架構下,用於編譯 Go 語言代碼的編譯器的名稱是 6g,鏈接器的名稱是 6l。用於編譯 C 語言代碼的編譯器的名稱是 6c。而用於編譯匯編語言代碼的編譯器的名稱為 6a。
- Go 語言的官方編譯器生成的結果文件會以 GOCHAR 的值作為擴展名。Go 語言的官方編譯器 6g 在對命令源碼文件編譯之后會把結果文件 go.6 存放到臨時工作目錄的相應位置中。
GOEXE
GOEXE 的值會被作為可執行文件的后綴。它的值與 GOOS 的值存在一定關系,即只有 GOOS 的值為“windows”時 GOEXE 的值才會是“.exe”,否則其值就為空字符串“”。這與在各個操作系統下的可執行文件的默認后綴是一致的。
GOHOSTARCH
GOHOSTARCH 的值的含義是程序運行環境的目標計算架構的標識,也就是程序在運行時所在的計算機系統的計算架構的名稱。在通常情況下,它的值不需要被顯式的設置。因為用來安裝Go語言的二進制分發文件和MSI(Microsoft 軟件安裝)軟件包文件都是平台相關的。所以,對於不同計算架構的 Go 語言環境來說,它都會是一個常量。
GOHOSTOS
GOHOSTOS 的值的含義是程序運行環境的目標操作系統的標識,也即程序在運行時所在的計算機系統的操作系統的名稱。與 GOHOSTARCH 類似,它的值在不同的操作系統下是固定不變的,同樣不需要顯式的設置。
GOPATH
這個環境信息我們在之前已經提到過很多次。它的值指明了Go語言工作區目錄的絕對路徑。我們需要顯式的設置環境變量 GOPATH。如果有多個工作區,那么多個工作區的絕對路徑之間需要用分隔符分隔。在 windows 操作系統下,這個分隔符為“;”。在其它操作系統下,這個分隔符為“:”。注意,GOPATH 的值不能與 GOROOT 的值相同。
GORACE
GORACE 的值包含了用於數據競爭檢測的相關選項。數據競爭是在並發程序中最常見和最難調試的一類 bug。數據競爭會發生在多個 Goroutine 爭相訪問相同的變量且至少有一個 Goroutine 中的程序在對這個變量進行寫操作的情況下。
數據競爭檢測需要被顯式的開啟。還記得標記 -race 嗎?我們可以通過在執行一些標准 go 命令時加入這個標記來開啟數據競爭檢測。在這種情況下,GORACE 的值就會被使用到了。支持 -race 標記的標准 go 命令包括:go test 命令、go run 命令、go build 命令和 go install 命令。
GORACE 的值形如“option1=val1 option2=val2”,即:選項名稱與選項值之間以等號“=”分隔,多個選項之間以空格“ ”分隔。數據競爭檢測的選項包括 log_path、exitcode、strip_path_prefix 和 history_size。為了設置 GORACE 的值,我們需要設置環境變量 GORACE。或者,我們也可以在執行 go 命令時臨時設置它,像這樣:
hc@ubt:~/golang/goc2p/src/cnet/ctcp$ GORACE="log_path=/home/hc/golang/goc2p /race/report strip_path_prefix=home/hc/golang/goc2p/" go test -race #
關於數據競爭檢測的更多細節我們將會在本書的第三部分予以說明。
GOROOT
GOROOT 會是我們在安裝 Go 語言時第一個碰到 Go 語言環境變量。它的值指明了 Go 語言的安裝目錄的絕對路徑。但是,只有在非默認情況下我們才需要顯式的設置環境變量 GOROOT。這里所說的默認情況是指:在 Windows 操作系統下我們把 Go 語言安裝到 c:\Go 目錄下,或者在其它操作系統下我們把 Go 語言安裝到 /usr/local/go 目錄下。另外,當我們不是通過二進制分發包來安裝 Go 語言的時候,也不需要設置環境變量 GOROOT 的值。比如,在 Windows 操作系統下,我們可以使用 MSI 軟件包文件來安裝 Go 語言。
GOTOOLDIR
GOTOOLDIR 的值指明了 Go 工具目錄的絕對路徑。根據 GOROOT、GOHOSTOS 和 GOHOSTARCH 來設置。其值為 $GOROOT/pkg/tool/$GOOS_$GOARCH。關於這個目錄,我們在之前也提到過多次。
除了上面介紹的這些通用的Go語言環境信息,還兩個針對於非 Plan 9 操作系統的環境信息。它們是 CC 和 GOGCCFLAGS。環境信息 CC 的值是操作系統默認的 C 語言編譯器的命令名稱。環境信息 GOGCCFLAGS 的值則是 Go 語言在使用操作系統的默認 C 語言編譯器對 C 語言代碼進行編譯時加入的參數。
如果我們要有針對性的查看上述的一個或多個環境信息,可以在 go env 命令的后面加入它們的名字並執行之。在 go env 命令和環境信息名稱之間需要用空格分隔,多個環境信息名稱之間也需要用空格分隔。示例如下:
hc@ubt:~$ go env GOARCH GOCHAR 386 8
上例的 go env 命令的輸出信息中,每一行對一個環境信息的值,且其順序與我們輸入的環境信息名稱的順序一致。比如,386 為環境信息 GOARCH,而8則是環境信息 GOCHAR 的值。
go env 命令能夠讓我們對當前的 Go 語言環境進行簡要的了解。通過它,我們也可以對當前安裝的 Go 語言的環境設置進行簡單的檢查。
摘自:
http://wiki.jikexueyuan.com/project/go-command-tutorial/0.14.html