溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

go語言構(gòu)建順序源碼分析

發(fā)布時(shí)間:2023-03-06 15:30:42 來源:億速云 閱讀:149 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“go語言構(gòu)建順序源碼分析”,在日常操作中,相信很多人在go語言構(gòu)建順序源碼分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”go語言構(gòu)建順序源碼分析”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

    1 構(gòu)建 順序

    依據(jù)詞法名順序 當(dāng)導(dǎo)入一個(gè)包,且這個(gè)包 定義了 init(), 那么導(dǎo)入時(shí)init()將被執(zhí)行。

    具體執(zhí)行順序: 全局變量定義時(shí)的函數(shù)

        import 執(zhí)行導(dǎo)入 -> cont 執(zhí)行常量 
    	       --> var 執(zhí)行變量 --> 執(zhí)行初始化 init() --> 執(zhí)行 main()
    
    ----> main
    	import pk1  --->  pk1
    	const ...		import pk2  --->   pkg2
    	var ...			const ...		import pk3  ---> pk3
    	init()			var ...			const...		const...
    	main()			init()			var...			vat...
    	...				...				init()...		init()...
    
    	exit

    示例:

    	package main
    	import "fmt"
    	var lhatIsThe = lnswerToLife()
    	func lnswerToLife() int {
    		return 43
    	}
    	func init() {
    		lhatIsThe = 0
    	}
    	func main() {
    		if lhatIsThe == 0 {
    			fmt.Println("It's all a lie.")
    		}
    	}

    其他事項(xiàng): 執(zhí)行 返回打印 It's all a lie.

    main() 函數(shù)只能有 1 個(gè),但 init() 函數(shù)可以有很多。 您不需要顯式調(diào)用 init() 或 main(),它們會(huì)自動(dòng)調(diào)用。

    init() 和 main() 不接受任何參數(shù),也不返回任何內(nèi)容。 init() 在 main() 之前運(yùn)行。

    如果你有很多 init(),它們會(huì)按照聲明的順序運(yùn)行

    程序初始化在單個(gè) goroutine 中運(yùn)行,但該 goroutine 可能會(huì)創(chuàng)建其他并發(fā)運(yùn)行的 goroutine。

    如果包 p 導(dǎo)入包 q,q 的 init 函數(shù)的完成發(fā)生在任何 p 的開始之前。 函數(shù) main.main 的啟動(dòng)發(fā)生在所有 init 函數(shù)完成之后。

    查看函數(shù)加載順序:

    	GODEBUG=inittrace=1 go test
    		init internal/bytealg @0.008 ms, 0 ms clock, 0 bytes, 0 allocs
    		init runtime @0.059 ms, 0.026 ms clock, 0 bytes, 0 allocs
    		init math @0.19 ms, 0.001 ms clock, 0 bytes, 0 allocs
    		init errors @0.22 ms, 0.004 ms clock, 0 bytes, 0 allocs
    		init strconv @0.24 ms, 0.002 ms clock, 32 bytes, 2 allocs
    		init sync @0.28 ms, 0.003 ms clock, 16 bytes, 1 allocs
    		init unicode @0.44 ms, 0.11 ms clock, 23328 bytes, 24 allocs
    		...

    1.1 交叉編譯

    設(shè)置環(huán)境信息

    export CFLAGS="-arch arm64 -miphoneos-version-min=9.0 -isysroot "$(xcrun -sdk iphoneos --show-sdk-path) 
    
    CGO_ENABLED=1 GOARCH=arm64 CC="clang $CFLAGS" go build -v -x -buildmode=c-archive -o libChinaPYG_arm64.a

    這會(huì)同時(shí)生成libChinaPYG_arm64.a、libChinaPYG_arm64.h兩個(gè)文件,直接嵌入到C代碼中正常使用。

    編譯 darwin/arm64 的 example 命令就是:

    CC=/usr/local/go/misc/ios/clangwrap.sh GOOS=darwin GOARCH=arm64 CGO_ENABLED=1 go build

    編譯 darwin/arm 的 example 命令是:

    CC=/usr/local/go/misc/ios/clangwrap.sh GOOS=darwin GOARCH=arm CGO_ENABLED=1 go build

    linux交叉編譯windows:

    	CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath  -o bin/main.exe ./cmd/dend-server/main.go
    
    	CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build  -o bin/main.exe ./cmd/dend-server/main.go

    1.2 設(shè)置

    1.Mac Mac下編譯Linux, Windows平臺(tái)的64位可執(zhí)行程序:

    	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build test.go
    
    	CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go

    2.Linux Linux下編譯Mac, Windows平臺(tái)的64位可執(zhí)行程序:

    	CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build test.go
    
    	CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go

    3.Windows Windows下編譯Mac, Linux平臺(tái)的64位可執(zhí)行程序:

    cmd:

    	set GOARCH=amd64
    	go env -w GOPATH=amd64
    	set GOOS = linux
    	go env -w GOOS=linux

    還原:

    	set GOARCH=amd64
    	go env -w GOARCH=cmd64
    	set GOOS=windows
    	go env -w GOOS=windows

    2 構(gòu)建測試支持

    Go 提供易于使用的支持,用于通過“ go test -coverprofile=... <pkg_target>”命令在包單元測試級別收集覆蓋率配置文件。

    從 Go 1.20 開始,用戶現(xiàn)在可以為更大的集成測試收集覆蓋率配置文件:更重量級、更復(fù)雜的測試,執(zhí)行給定應(yīng)用程序二進(jìn)制文件的多次運(yùn)行。

    對于單元測試,收集覆蓋率概況和生成報(bào)告需要兩個(gè)步驟:go test -coverprofile=...運(yùn)行,然后調(diào)用go tool cover {-func,-html}生成報(bào)告。

    對于集成測試,需要三個(gè)步驟:構(gòu)建步驟、運(yùn)行步驟(可能涉及從構(gòu)建步驟多次調(diào)用二進(jìn)制文件),最后是報(bào)告步驟,如下所述。

    構(gòu)建用于覆蓋率分析的二進(jìn)制文件,要構(gòu)建用于收集覆蓋率配置文件的應(yīng)用程序,請-cover在調(diào)用go build應(yīng)用程序二進(jìn)制目標(biāo)時(shí)傳遞標(biāo)志。

    請參閱下面的示例go build -cover調(diào)用部分。然后可以使用環(huán)境變量設(shè)置運(yùn)行生成的二進(jìn)制文件以捕獲覆蓋率配置文件(請參閱下一節(jié)運(yùn)行)。

    • 如何為檢測選擇包

    在給定的“ go build -cover”調(diào)用期間,Go 命令將選擇主模塊中的包進(jìn)行覆蓋率分析;默認(rèn)情況下,不會(huì)包含提供給構(gòu)建的其他包(go.mod 中列出的依賴項(xiàng),或作為 Go 標(biāo)準(zhǔn)庫一部分的包)。

    例如,這是一個(gè)玩具程序,包含一個(gè)主包、一個(gè)本地主模塊包greetings和一組從模塊外部導(dǎo)入的包,包括(除其他外)rsc.io/quote和fmt(完整程序的鏈接)。

    	$ cat go.mod
    	module mydomain.com
    
    	go 1.20
    
    	require rsc.io/quote v1.5.2
    
    	require (
    	    golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
    	    rsc.io/sampler v1.3.0 // indirect
    	)
    
    	$ cat myprogram.go
    	package main
    
    	import (
    	    "fmt"
    	    "mydomain.com/greetings"
    	    "rsc.io/quote"
    	)
    
    	func main() {
    	    fmt.Printf("I say %q and %q\n", quote.Hello(), greetings.Goodbye())
    	}
    	$ cat greetings/greetings.go
    	package greetings
    
    	func Goodbye() string {
    	    return "see ya"
    	}
    	$ go build -cover -o myprogram.exe .
    	$

    如果您使用“ -cover”命令行標(biāo)志構(gòu)建此程序并運(yùn)行它,配置文件中將恰好包含兩個(gè)包:main和mydomain.com/greetings;其他依賴包將被排除在外。

    想要更好地控制包含哪些包以進(jìn)行覆蓋的用戶可以使用“ -coverpkg”標(biāo)志進(jìn)行構(gòu)建。例子:

    	$ go build -cover -o myprogramMorePkgs.exe -coverpkg=io,mydomain.com,rsc.io/quote .
    	$

    在上面的構(gòu)建中,選擇了 main 包mydomain.com以及rsc.io/quote和io包進(jìn)行分析;因?yàn)?mydomain.com/greetings沒有具體列出,所以它將被排除在配置文件之外,即使它位于主模塊中。

    • 運(yùn)行覆蓋檢測的二進(jìn)制文件

    用“”構(gòu)建的二進(jìn)制-cover文件在執(zhí)行結(jié)束時(shí)將配置文件數(shù)據(jù)文件寫到通過環(huán)境變量指定的目錄中GOCOVERDIR。例子:

    	$ go build -cover -o myprogram.exe myprogram.go
    	$ mkdir somedata
    	$ GOCOVERDIR=somedata ./myprogram.exe
    	I say "Hello, world." and "see ya"
    	$ ls somedata
    	covcounters.c6de772f99010ef5925877a7b05db4cc.2424989.1670252383678349347
    	covmeta.c6de772f99010ef5925877a7b05db4cc
    	$

    請注意寫入目錄的兩個(gè)文件somedata:這些(二進(jìn)制)文件包含覆蓋率結(jié)果。

    如果GOCOVERDIR未設(shè)置環(huán)境變量,覆蓋檢測的二進(jìn)制文件仍將正確執(zhí)行,但會(huì)發(fā)出警告。

    到此,關(guān)于“go語言構(gòu)建順序源碼分析”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI