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

關鍵部分解釋:

使用命令

編譯構建

$ 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