常用作編譯命令行指定的單個go源碼包。會生成一個以文件.o為后綴的目標文件,其文件名與包內第一個源文件的文件名相同。 目標文件可以與其他對象組合成一個包檔案或直接傳遞給鏈接器(go tool link)。如果使用-pack調用,編譯器會直接寫入一個檔案(archive),繞過中間目標文件。
生成的文件包含有關由包導出的符號的類型信息,以及包使用的從其他包導入的符號使用的類型。因此,在編譯包P的客戶端C讀取P的依賴關系文件時,不需要編譯P的輸出。
命令行
go tool compile [flags] file...
指定的文件必須是Go源文件和同一個包下的其他部分。所有目標操作系統和體系結構都使用相同的編譯器。 GOOS和GOARCH環境變量設置了所需的屬性。
-D path 設置本地導入的相對路徑。 -I dir1 -I dir2 在dir1,dir2等文件夾搜索導入的包, 會先查詢 $GOROOT/pkg/$GOOS_$GOARCH. -L 在錯誤消息中顯示完整的文件路徑。 -N 禁用優化。 -S 將匯編列表打印到標准輸出(僅限代碼)。 -S -S 將匯編列表打印到標准輸出(代碼和數據)。 -V 打印編譯器版本並退出。 -asmhdr file 將匯編頭寫入文件。 -blockprofile file 編寫用於編譯到文件的塊配置文件。 -complete 假設軟件包沒有非Go組件。 -cpuprofile file 編寫用於編譯文件的CPU配置文件。 -dynlink 允許引用共享庫中的Go符號(實驗性功能)。 -e 移除報告錯誤數量限制(默認限制為10)。 -h 在檢測到第一個錯誤時暫停堆棧跟蹤。 -importmap old=new 在編譯過程中將導入“舊”解釋為導入“新”。 該選項可以重復添加。 -installsuffix suffix 在 $GOROOT/pkg/$GOOS_$GOARCH_suffix 查找包 而非 $GOROOT/pkg/$GOOS_$GOARCH. -l 禁用內聯。 -largemodel 生成假定大內存模型的代碼。 -linkobj file 將鏈接器特定的對象寫入文件和編譯器特定的對象 對象到通常的輸出文件(由-o指定)。 沒有這個標志,-o輸出是兩者的組合 鏈接器和編譯器輸入。 -memprofile file 寫入內存配置文件。 -memprofilerate rate 設置 runtime.MemProfileRate 調整編譯速度。 -msan 將調用插入到C/C++內存清理程序。 -mutexprofile file 編寫用於編譯文件的互斥量配置文件。 -nolocalimports 禁止本地(相對)導入。 -o file 將目標寫入文件(默認file.o或與-pack,file.a)。 -p path 為正在編譯的代碼設置期望的包導入路徑, 並診斷會導致循環依賴的導入。 -pack 編寫一個包(歸檔)文件而不是一個目標文件 -race 編譯啟用競爭檢測器。 -trimpath prefix 從記錄的源文件路徑中刪除前綴。 -u 禁止導入未標記為安全的軟件包;意味着 -nolocalimports.
還有一些調試標志;運行該命令時沒有使用消息的參數。
編譯指令
編譯器在行的開頭以//注釋的形式接受編譯器指令。為了將它們與非指令注釋區分開來,指令在斜線和指令名稱之間不需要空格。但由於它們是注釋,不知道指令約定或特定指令的工具可以像跳過其他注釋一樣跳過指令。
//line path/to/file:linenumber
//line指令指定后面的源代碼行應該被記錄為來自給定的文件路徑和行號。連續的行使用遞增的行號記錄,直到下一個指令。該指令通常出現在機器生成的代碼中,因此編譯器和調試器將在生成器的原始輸入中顯示行。
//line指令是一個歷史的特例;所有其他指令的格式為//go:name,表示該指令是由Go工具鏈定義的。
//go:noescape
//go:noescape指令指定文件中的下一個聲明,它必須是一個沒有body的func(意思是它有一個不用Go編寫的實現),不允許任何作為參數傳遞的指針轉義到堆或從函數返回的值。在調用函數的Go代碼的編譯器轉義分析期間,可以使用這些信息。
//go:nosplit
//go:nosplit指令指定文件中聲明的下一個函數不能包含堆棧溢出檢查。在調用goroutine被搶占的時候,調用低級運行時源的情況最為常見。
//go:linkname localname importpath.name
//go:linkname指令指示編譯器使用“importpath.name”作為源代碼中聲明為“localname”的變量或函數的目標文件符號名稱。因為這個指令可以顛覆類型系統和包模塊化,所以只有在導入 unsafe 包的文件中才能使用。