Go 項目使用 Makefile 構建版本信息完整教程
目錄結構
我們以最小目錄結構爲例進行說明,如下這是我們此次示例的目錄結構。
$ tree -L 3
.
├── main.go
├── Makefile
├── pkg
│ └── version
│ └── version.go
├── README.md
代碼內容
主要有兩部分代碼,分別爲 main.go
,內容如下:
package main
import (
"eastMoney/pkg/version"
)
func main() {
version.GetInfo()
}
version.go
內容如下:
package version
import (
"encoding/json"
"fmt"
"os"
"runtime"
)
var (
gitTag string = ""
gitCommit string = ""
gitBranch string = ""
gitTreeState string = ""
buildDate string = ""
version string = ""
)
type info struct {
GitTag string `json:"gitTag"`
GitCommit string `json:"gitCommit"`
GitBranch string `json:"gitBranch"`
GitTreeState string `json:"gitTreeState"`
BuildDate string `json:"buildDate"`
GoVersion string `json:"goVersion"`
Compiler string `json:"compiler"`
Platform string `json:"platform"`
Version string `json:"version"`
}
func GetInfo() {
v := info{
GitTag: gitTag,
GitCommit: gitCommit,
GitBranch: gitBranch,
GitTreeState: gitTreeState,
BuildDate: buildDate,
GoVersion: runtime.Version(),
Compiler: runtime.Compiler,
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
Version: version,
}
marshalled, err := json.MarshalIndent(&v, "", " ")
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
}
fmt.Println(string(marshalled))
}
Makefile
我們編寫的 Makefile
文件如下:
SHELL := /bin/bash
BASEDIR = $(shell pwd)
SRC = $(shell find . -type f -name '*.go' -not -path "./vendor/*")
VERSION := v3.0.0
ENV := dev
VersionDir = eastMoney/pkg/version
# gitHash 當前最新的 commit id, 與 gitCommit 結果相同
gitHash = $(shell git rev-parse HEAD)
gitBranch = $(shell git rev-parse --abbrev-ref HEAD)
gitTag = $(shell \
if [ "`git describe --tags --abbrev=0 2>/dev/null`" != "" ]; \
then \
git describe --tags --abbrev=0; \
else \
git log --pretty=format:'%h' -n 1; \
fi)
# 與前面的 gitHash 相同
gitCommit = $(shell git log --pretty=format:'%H' -n 1)
gitTreeState = $(shell if git status | grep -q 'clean'; then echo clean; else echo dirty; fi)
buildDate = $(shell TZ=Asia/Shanghai date +%FT%T%z)
# buildDate = $(shell TZ=Asia/Shanghai date +%F\ %T%z | tr 'T' ' ')
ifeq ($(ENV), dev)
BUILD_FLAGS = -race
endif
ifeq ($(ENV), pro)
LDFLAGS = -w
endif
LDFLAGS += -X "${VersionDir}.gitTag=${gitTag}"
LDFLAGS += -X "${VersionDir}.buildDate=${buildDate}"
LDFLAGS += -X "${VersionDir}.gitCommit=${gitCommit}"
LDFLAGS += -X "${VersionDir}.gitTreeState=${gitTreeState}"
LDFLAGS += -X "${VersionDir}.gitBranch=${gitBranch}"
LDFLAGS += -X "${VersionDir}.version=${VERSION}"
all: lint build
build:
go build -v -ldflags '$(LDFLAGS)' $(BUILD_FLAGS) -gcflags=all="-N -l" -o east_money .
lint:
go fmt ./...
go vet ./...
goimports -w .
# golangci-lint run ./...
# cover:
# go test ./... -v -short -coverprofile .coverage.txt
# go tool cover -func .coverage.txt
# 刪除指定目錄(包括子目錄)下所有擴展名爲 .sa、.sb、.sc、...、.sz 的隱藏文件(以 . 開頭,且緊接着字符 _ 或 .)全部刪除
clean:
rm -f east_money || true
find . -name "[._]*.s[a-w][a-z]" | xargs -i rm -f {} || true
rm -rf ./log || true
help:
@echo "make build - compile the source code"
@echo "make clean - remove binary file and vim swp files"
@echo "make lint - run go tool 'fmt', 'vet', 'goimports', 'golangci-lint' "
.PHONY: clean help
關鍵部分解釋:
-
VERSION := v3.0.0
自定義項目代碼的版本號; -
ENV := dev
編譯環境,測試環境 ->dev
生產環境 ->pro
; -
VersionDir = eastMoney/pkg/version
代碼中version.go
文件的包路徑; -
LDFLAGS = -w
-w
爲去掉調試信息(無法使用 gdb 調試),這樣可以使編譯後的二進制文件更小; -
-gcflags=all="-N -l" all
表示這些標誌將應用於所有Go
源文件,而不是僅應用於特定的文件,-N
: 禁用編譯器優化,對調試有幫助
-l
: 生成較小的二進制文件 -
格式化代碼和源碼靜態檢查,
./…
會遞歸執行該目錄下所有子目錄文件,-w
: 寫入模式,表示對匹配的文件進行格式化並寫回文件; -
|| true
目的是避免前面命令執行失敗導致腳本退出; -
@
放在行首,表示不打印此行。默認在編譯的過程中,會把此行的展開效果字符串打印出來; -
.PHONY
是個僞目標,形式上是一個目標,但是不需要依賴,僞目標一般只是爲了執行目標下面的命令(比如clean
就是僞目標);
使用命令
編譯構建
$ make ENV=dev
go fmt ./...
go vet ./...
goimports -w .
# golangci-lint run ./...
go build -v -ldflags '-X "eastMoney/pkg/version.gitTag=v1.0.0" -X "eastMoney/pkg/version.buildDate=2024-08-27T22:43:24+0800" -X "eastMoney/pkg/version.gitCommit=be4c87f6ec4950a046332bf36c004780da021ad5" -X "eastMoney/pkg/version.gitTreeState=dirty" -X "eastMoney/pkg/version.gitBranch=master" -X "eastMoney/pkg/version.version=v3.0.0"' -race -gcflags=all="-N -l" -o east_money .
eastMoney
執行
$ ./east_money
{
"gitTag": "v1.0.0",
"gitCommit": "be4c87f6ec4950a046332bf36c004780da021ad5",
"gitBranch": "master",
"gitTreeState": "dirty",
"buildDate": "2024-08-27T22:43:24+0800",
"goVersion": "go1.21.1",
"compiler": "gc",
"platform": "linux/amd64",
"version": "v3.0.0"
}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/YHyPS7bYvs7a_ilognPo8Q