成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我最喜歡的 Go 構(gòu)建選項(xiàng)

開發(fā) 后端
這些方便的 Go 構(gòu)建選項(xiàng)可以幫助你更好地理解 Go 的編譯過程。

學(xué)習(xí)一門新的編程語言最令人欣慰的部分之一,就是最終運(yùn)行了一個(gè)可執(zhí)行文件,并獲得預(yù)期的輸出。當(dāng)我開始學(xué)習(xí) Go 這門編程語言時(shí),我先是閱讀一些示例程序來熟悉語法,然后是嘗試寫一些小的測試程序。隨著時(shí)間的推移,這種方法幫助我熟悉了編譯和構(gòu)建程序的過程。

Go 的構(gòu)建選項(xiàng)提供了更好地控制構(gòu)建過程的方法。它們還可以提供額外的信息,幫助把這個(gè)過程分成更小的部分。在這篇文章中,我將演示我所使用的一些選項(xiàng)。注意:我使用的“構(gòu)建build”和“編譯compile”這兩個(gè)詞是同一個(gè)意思。

開始使用 Go

我使用的 Go 版本是 1.16.7。但是,這里給出的命令應(yīng)該也能在最新的版本上運(yùn)行。如果你沒有安裝 Go,你可以從 ??Go 官網(wǎng)?? 上下載它,并按照說明進(jìn)行安裝。你可以通過打開一個(gè)命令提示符,并鍵入下面的命令來驗(yàn)證你所安裝的版本:

$ go version

你應(yīng)該會(huì)得到類似下面這樣的輸出,具體取決于你安裝的版本:

go version go1.16.7 linux/amd64

基本的 Go 程序的編譯和執(zhí)行方法

我將從一個(gè)在屏幕上簡單打印 “Hello World” 的 Go 程序示例開始,就像下面這樣:

$ cat hello.go
package main

import "fmt"

func main() {
fmt.Println("Hello World")
}

在討論更高級(jí)的選項(xiàng)之前,我將解釋如何編譯這個(gè) Go 示例程序。我使用了 ??build?? 命令,后面跟著 Go 程序的源文件名,本例中是 ??hello.go??,就像下面這樣:

$ go build hello.go

如果一切工作正常,你應(yīng)該看到在你的當(dāng)前目錄下創(chuàng)建了一個(gè)名為 ??hello?? 的可執(zhí)行文件。你可以通過使用 ??file?? 命令驗(yàn)證它是 ELF 二進(jìn)制可執(zhí)行格式(在 Linux 平臺(tái)上)。你也可以直接執(zhí)行它,你會(huì)看到它輸出 “Hello World”。

$ ls
hello  hello.go

$ file ./hello
./hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

$ ./hello
Hello World

Go 提供了一個(gè)方便的 ??run?? 命令,以便你只是想看看程序是否能正常工作,并獲得預(yù)期的輸出,而不想生成一個(gè)最終的二進(jìn)制文件。請(qǐng)記住,即使你在當(dāng)前目錄中沒有看到可執(zhí)行文件,Go 仍然會(huì)在某個(gè)地方編譯并生成可執(zhí)行文件并運(yùn)行它,然后把它從系統(tǒng)中刪除。我將在本文后面的章節(jié)中解釋。

$ go run hello.go
Hello World

$ ls
hello.go

更多細(xì)節(jié)

上面的命令就像一陣風(fēng)一樣,一下子就運(yùn)行完了我的程序。然而,如果你想知道 Go 在編譯這些程序的過程中做了什么,Go 提供了一個(gè) ??-x?? 選項(xiàng),它可以打印出 Go 為產(chǎn)生這個(gè)可執(zhí)行文件所做的一切。

簡單看一下你就會(huì)發(fā)現(xiàn),Go 在 ??/tmp?? 內(nèi)創(chuàng)建了一個(gè)臨時(shí)工作目錄,并生成了可執(zhí)行文件,然后把它移到了 Go 源程序所在的當(dāng)前目錄。

$ go build -x hello.go

WORK=/tmp/go-build1944767317
mkdir -p $WORK/b001/

<< snip >>

mkdir -p $WORK/b001/exe/
cd .
/usr/lib/golang/pkg/tool/linux_amd64/link -o $WORK \
/b001/exe/a.out -importcfg $WORK/b001 \
/importcfg.link -buildmode=exe -buildid=K26hEYzgDkqJjx2Hf-wz/\
nDueg0kBjIygx25rYwbK/W-eJaGIOdPEWgwC6o546 \
/K26hEYzgDkqJjx2Hf-wz -extld=gcc /root/.cache/go-build /cc \
/cc72cb2f4fbb61229885fc434995964a7a4d6e10692a23cc0ada6707c5d3435b-d
/usr/lib/golang/pkg/tool/linux_amd64/buildid -w $WORK \
/b001/exe/a.out # internal
mv $WORK/b001/exe/a.out hello
rm -r $WORK/b001/

這有助于解決在程序運(yùn)行后卻在當(dāng)前目錄下沒有生成可執(zhí)行文件的謎團(tuán)。使用 ??-x?? 顯示可執(zhí)行文件確實(shí)在 ??/tmp?? 工作目錄下創(chuàng)建并被執(zhí)行了。然而,與 ??build?? 命令不同的是,可執(zhí)行文件并沒有移動(dòng)到當(dāng)前目錄,這使得看起來沒有可執(zhí)行文件被創(chuàng)建。

$ go run -x hello.go


mkdir -p $WORK/b001/exe/
cd .
/usr/lib/golang/pkg/tool/linux_amd64/link -o $WORK/b001 \
/exe/hello -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=hK3wnAP20DapUDeuvAAS/E_TzkbzwXz6tM5dEC8Mx \
/7HYBzuaDGVdaZwSMEWAa/hK3wnAP20DapUDeuvAAS -extld=gcc \
/root/.cache/go-build/75/ \
7531fcf5e48444eed677bfc5cda1276a52b73c62ebac3aa99da3c4094fa57dc3-d
$WORK/b001/exe/hello
Hello World

模仿編譯而不產(chǎn)生可執(zhí)行文件

假設(shè)你不想編譯程序并產(chǎn)生一個(gè)實(shí)際的二進(jìn)制文件,但你確實(shí)想看到這個(gè)過程中的所有步驟。你可以通過使用 ??-n?? 這個(gè)構(gòu)建選項(xiàng)來做到這一點(diǎn),該選項(xiàng)會(huì)打印出通常的執(zhí)行步驟,而不會(huì)實(shí)際創(chuàng)建二進(jìn)制文件。

$ go build -n hello.go

保存臨時(shí)目錄

很多工作都發(fā)生在 ??/tmp?? 工作目錄中,一旦可執(zhí)行文件被創(chuàng)建和運(yùn)行,它就會(huì)被刪除。但是如果你想看看哪些文件是在編譯過程中創(chuàng)建的呢?Go 提供了一個(gè) ??-work?? 選項(xiàng),它可以在編譯程序時(shí)使用。??-work?? 選項(xiàng)除了運(yùn)行程序外,還打印了工作目錄的路徑,但它并不會(huì)在這之后刪除工作目錄,所以你可以切換到該目錄,檢查在編譯過程中創(chuàng)建的所有文件。

$ go run -work hello.go
WORK=/tmp/go-build3209320645
Hello World

$ find /tmp/go-build3209320645
/tmp/go-build3209320645
/tmp/go-build3209320645/b001
/tmp/go-build3209320645/b001/importcfg.link
/tmp/go-build3209320645/b001/exe
/tmp/go-build3209320645/b001/exe/hello

$ /tmp/go-build3209320645/b001/exe/hello
Hello World

其他編譯選項(xiàng)

如果說,你想手動(dòng)編譯程序,而不是使用 Go 的 ??build?? 和 ??run?? 這兩個(gè)方便的命令,最后得到一個(gè)可以直接由你的操作系統(tǒng)(這里指 Linux)運(yùn)行的可執(zhí)行文件。那么,你該怎么做呢?這個(gè)過程可以分為兩部分:編譯和鏈接。你可以使用 ??tool?? 選項(xiàng)來看看它是如何工作的。

首先,使用 ??tool compile?? 命令產(chǎn)生結(jié)果的 ??ar?? 歸檔文件,它包含了 ??.o?? 中間文件。接下來,對(duì)這個(gè) ??hello.o?? 文件執(zhí)行 ??tool link?? 命令,產(chǎn)生最終的可執(zhí)行文件,然后你就可以運(yùn)行它了。

$ go tool compile hello.go

$ file hello.o
hello.o: current ar archive

$ ar t hello.o
__.PKGDEF
_go_.o

$ go tool link -o hello hello.o

$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

$ ./hello
Hello World

如果你想進(jìn)一步查看基于 ??hello.o?? 文件產(chǎn)生可執(zhí)行文件的鏈接過程,你可以使用 ??-v?? 選項(xiàng),它會(huì)搜索每個(gè) Go 可執(zhí)行文件中包含的 ??runtime.a?? 文件。

$ go tool link -v -o hello hello.o
HEADER = -H5 -T0x401000 -R0x1000
searching for runtime.a in /usr/lib/golang/pkg/linux_amd64/runtime.a
82052 symbols, 18774 reachable
1 package symbols, 1106 hashed symbols, 77185 non-package symbols, 3760 external symbols
81968 liveness data

交叉編譯選項(xiàng)

現(xiàn)在我已經(jīng)解釋了 Go 程序的編譯過程,接下來,我將演示 Go 如何通過在實(shí)際的 ??build?? 命令之前提供 ??GOOS?? 和 ??GOARCH?? 這兩個(gè)環(huán)境變量,來允許你構(gòu)建針對(duì)不同硬件架構(gòu)和操作系統(tǒng)的可執(zhí)行文件。

這有什么用呢?舉個(gè)例子,你會(huì)發(fā)現(xiàn)為 ARM(arch64)架構(gòu)制作的可執(zhí)行文件不能在英特爾(x86_64)架構(gòu)上運(yùn)行,而且會(huì)產(chǎn)生一個(gè) Exec 格式錯(cuò)誤。

下面的這些選項(xiàng)使得生成跨平臺(tái)的二進(jìn)制文件變得小菜一碟:

$ GOOS=linux GOARCH=arm64 go build hello.go

$ file ./hello
./hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped

$ ./hello
bash: ./hello: cannot execute binary file: Exec format error

$ uname -m
x86_64

你可以閱讀我之前的博文,以更多了解我在 ??使用 Go 進(jìn)行交叉編譯?? 方面的經(jīng)驗(yàn)。

查看底層匯編指令

源代碼并不會(huì)直接轉(zhuǎn)換為可執(zhí)行文件,盡管它生成了一種中間匯編格式,然后最終被組裝為可執(zhí)行文件。在 Go 中,這被映射為一種中間匯編格式,而不是底層硬件匯編指令。

要查看這個(gè)中間匯編格式,請(qǐng)?jiān)谑褂?nbsp;??build?? 命令時(shí),提供 ??-gcflags?? 選項(xiàng),后面跟著 ??-S??。這個(gè)命令將會(huì)顯示使用到的匯編指令:

$ go build -gcflags="-S" hello.go
# command-line-arguments
"".main STEXT size=138 args=0x0 locals=0x58 funcid=0x0
0x0000 00000 (/test/hello.go:5) TEXT "".main(SB), ABIInternal, $88-0
0x0000 00000 (/test/hello.go:5) MOVQ (TLS), CX
0x0009 00009 (/test/hello.go:5) CMPQ SP, 16(CX)
0x000d 00013 (/test/hello.go:5) PCDATA $0, $-2
0x000d 00013 (/test/hello.go:5) JLS 128

<< snip >>

你也可以使用 ??objdump -s?? 選項(xiàng),來查看已經(jīng)編譯好的可執(zhí)行程序的匯編指令,就像下面這樣:

$ ls
hello hello.go

$ go tool objdump -s main.main hello
TEXT main.main(SB) /test/hello.go
hello.go:5 0x4975a0 64488b0c25f8ffffff MOVQ FS:0xfffffff8, CX
hello.go:5 0x4975a9 483b6110 CMPQ 0x10(CX), SP
hello.go:5 0x4975ad 7671 JBE 0x497620
hello.go:5 0x4975af 4883ec58 SUBQ $0x58, SP
hello.go:6 0x4975d8 4889442448 MOVQ AX, 0x48(SP)

<< snip >>

分離二進(jìn)制文件以減少其大小

Go 的二進(jìn)制文件通常比較大。例如, 一個(gè)簡單的 “Hello World” 程序?qū)?huì)產(chǎn)生一個(gè) 1.9M 大小的二進(jìn)制文件。

$ go build hello.go
$
$ du -sh hello
1.9M    hello
$
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$

為了減少生成的二進(jìn)制文件的大小,你可以分離執(zhí)行過程中不需要的信息。使用 ??-ldflags?? 和 ??-s -w?? 選項(xiàng)可以使生成的二進(jìn)制文件略微變小為 1.3M。

$ go build -ldflags="-s -w" hello.go
$
$ du -sh hello
1.3M    hello
$
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
$

總結(jié)

我希望這篇文章向你介紹了一些方便的 Go 編譯選項(xiàng),同時(shí)幫助了你更好地理解 Go 編譯過程。關(guān)于構(gòu)建過程的其他信息和其他有趣的選項(xiàng),請(qǐng)參考 Go 命令幫助:

$ go help build

題圖由 ??Ashraf Chemban??? 在 ???Pixabay?? 上發(fā)布。 

責(zé)任編輯:龐桂玉 來源: Linux中國
相關(guān)推薦

2020-08-06 15:14:07

D語言編程語言

2024-11-05 09:42:59

開發(fā)軟件命令行

2012-04-28 09:14:50

編程編程語錄

2021-10-27 14:55:57

Mark TextMarkdown編輯器

2021-01-14 23:14:40

開源Linux生產(chǎn)力應(yīng)用

2022-01-03 07:46:36

Linux應(yīng)用程序操作系統(tǒng)

2012-03-30 13:56:17

編程開發(fā)

2013-10-08 09:34:57

編程漫畫編程漫畫

2016-03-02 15:13:54

面試開發(fā)者問題

2024-03-13 13:39:21

2012-02-02 16:42:24

Android用戶

2020-02-10 10:05:12

Linux發(fā)行版Ubuntu

2020-08-29 18:51:14

效能工具效率生產(chǎn)力

2013-10-17 11:15:19

2021-03-09 11:09:10

LinuxWindows應(yīng)用程序

2024-06-28 13:57:34

2018-01-31 14:20:36

Linux分區(qū)管理fdisk

2018-11-21 15:09:53

勒索軟件遠(yuǎn)程桌面協(xié)議攻擊

2021-06-04 09:09:05

FlutterFuchsia操作系統(tǒng)

2022-01-05 08:56:20

Vue修飾符面試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲福利| 亚洲风情在线观看 | 国产美女在线免费观看 | a级在线观看 | 欧美黑人狂野猛交老妇 | 日本久久网 | 日韩一区二区在线播放 | 免费在线观看91 | 成人在线观看中文字幕 | 国产精品久久久久久久久久免费看 | 日本一区二区视频 | 亚洲自拍偷拍av | 成人精品视频在线观看 | 中文字幕一区二区三区四区五区 | 老司机久久 | 欧美精品一区在线 | ww亚洲ww亚在线观看 | 欧美bondage紧缚视频 | www.夜夜草 | 特级丰满少妇一级aaaa爱毛片 | 亚洲午夜av| 国产成人精品区一区二区不卡 | 天天看天天爽 | 一区二区三区高清在线观看 | 亚洲精品小视频在线观看 | 欧美日韩亚洲视频 | 成人免费观看视频 | 亚洲视频中文字幕 | 女同videos另类 | 97中文视频 | 无码国模国产在线观看 | 视频一区二区在线观看 | 成人国产在线视频 | 国产精品久久久久久52avav | 精品91久久久 | 亚洲精选久久 | 午夜精品一区二区三区在线视 | 色婷婷一区二区三区四区 | 亚洲综合小视频 | 99久久久无码国产精品 | 亚洲视频在线观看 |