@cyysu
2017-10-13T09:09:48.000000Z
字数 5076
阅读 1047
- 时间:2017年10月13日
- 作者:Kali
- 邮箱:cyysu.github.io@gmail.com
- 版本:3.0
- 描述:Makefile-项目二,介绍一片编译go程序的makefile
Makefile系列教程
# 定义模块名字PACKAGE = hellogopher# 设置时间DATE ?= $(shell date +%FT%T%z)# git describe命令显示离当前提交最近的标签。如果第一条命令执行成功 ,那么就不会执行第二条命令VERSION ?= $(shell git describe --tags --always --dirty --match=v* 2> /dev/null || \cat $(CURDIR)/.version 2> /dev/null || echo v0)GOPATH = $(CURDIR)/.gopath~BIN = $(GOPATH)/binBASE = $(GOPATH)/src/$(PACKAGE)# 这里的逻辑我们先不分析,后面有需要在去分析PKGS = $(or $(PKG),$(shell cd $(BASE) && env GOPATH=$(GOPATH) $(GO) list ./... | grep -v "^$(PACKAGE)/vendor/"))TESTPKGS = $(shell env GOPATH=$(GOPATH) $(GO) list -f '{{ if or .TestGoFiles .XTestGoFiles }}{{ .ImportPath }}{{ end }}' $(PKGS))GO = goGODOC = godocGOFMT = gofmtTIMEOUT = 15V = 0# 在V中找到属于1的字符串,如果找到了返回就是空,如果没有找到返回的就是@ 如果用在命令前面就是不回显命令Q = $(if $(filter 1,$V),,@)M = $(shell printf "\033[34;1m▶\033[0m").PHONY: all# ; 表示这个之后就是命令,这个时本目标开头先执行的# | 这个我查找了一下也没有找到具体意义,我写了一个测试发现没什么作用。可能就是一个规范,如果目标时变量,前面就加上 | 这个大家先这么记住,如果后面遇到我会告诉大家# @ 这个也是没有找到定义的,目前只能当做是规范。all: fmt lint vendor | $(BASE) ; $(info $(M) building executable…) @ ## Build program binary$Q cd $(BASE) && $(GO) build \-tags release \-ldflags '-X $(PACKAGE)/cmd.Version=$(VERSION) -X $(PACKAGE)/cmd.BuildDate=$(DATE)' \-o bin/$(PACKAGE) main.go# $@ 表示目标 这里表示$(BASE)# 这个目标表示将项目文件复制链接到GOPATH目录$(BASE): ; $(info $(M) setting GOPATH…)@mkdir -p $(dir $@)@ln -sf $(CURDIR) $@# ToolsGODEP = $(BIN)/depGODEPVERSION = 0.3.1#go get -d 表示让命令只执行下载操作,而不执行安装动作$(BIN)/dep: | $(BASE) ; $(info $(M) building go dep…)$Q go get -d github.com/golang/dep/cmd/dep$Q cd $(GOPATH)/src/github.com/golang/dep ; git checkout -q v$(GODEPVERSION)$Q go get github.com/golang/dep/cmd/depGOLINT = $(BIN)/golint$(BIN)/golint: | $(BASE) ; $(info $(M) building golint…)$Q go get github.com/golang/lint/golintGOCOVMERGE = $(BIN)/gocovmerge$(BIN)/gocovmerge: | $(BASE) ; $(info $(M) building gocovmerge…)$Q go get github.com/wadey/gocovmergeGOCOV = $(BIN)/gocov$(BIN)/gocov: | $(BASE) ; $(info $(M) building gocov…)$Q go get github.com/axw/gocov/...GOCOVXML = $(BIN)/gocov-xml$(BIN)/gocov-xml: | $(BASE) ; $(info $(M) building gocov-xml…)$Q go get github.com/AlekSi/gocov-xmlGO2XUNIT = $(BIN)/go2xunit$(BIN)/go2xunit: | $(BASE) ; $(info $(M) building go2xunit…)$Q go get github.com/tebeka/go2xunit# TestsTEST_TARGETS := test-default test-bench test-short test-verbose test-race.PHONY: $(TEST_TARGETS) test-xml check test teststest-bench: ARGS=-run=__absolutelynothing__ -bench=. ## Run benchmarkstest-short: ARGS=-short ## Run only short teststest-verbose: ARGS=-v ## Run tests in verbose mode with coverage reportingtest-race: ARGS=-race ## Run tests with race detector$(TEST_TARGETS): NAME=$(MAKECMDGOALS:test-%=%)$(TEST_TARGETS): testcheck test tests: fmt lint vendor | $(BASE) ; $(info $(M) running $(NAME:%=% )tests…) @ ## Run tests$Q cd $(BASE) && $(GO) test -timeout $(TIMEOUT)s $(ARGS) $(TESTPKGS)test-xml: fmt lint vendor | $(BASE) $(GO2XUNIT) ; $(info $(M) running $(NAME:%=% )tests…) @ ## Run tests with xUnit output$Q cd $(BASE) && 2>&1 $(GO) test -timeout 20s -v $(TESTPKGS) | tee test/tests.output$(GO2XUNIT) -fail -input test/tests.output -output test/tests.xmlCOVERAGE_MODE = atomicCOVERAGE_PROFILE = $(COVERAGE_DIR)/profile.outCOVERAGE_XML = $(COVERAGE_DIR)/coverage.xmlCOVERAGE_HTML = $(COVERAGE_DIR)/index.html.PHONY: test-coverage test-coverage-toolstest-coverage-tools: | $(GOCOVMERGE) $(GOCOV) $(GOCOVXML)test-coverage: COVERAGE_DIR := $(CURDIR)/test/coverage.$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")test-coverage: fmt lint vendor test-coverage-tools | $(BASE) ; $(info $(M) running coverage tests…) @ ## Run coverage tests$Q mkdir -p $(COVERAGE_DIR)/coverage$Q cd $(BASE) && for pkg in $(TESTPKGS); do \$(GO) test \-coverpkg=$$($(GO) list -f '{{ join .Deps "\n" }}' $$pkg | \grep '^$(PACKAGE)/' | grep -v '^$(PACKAGE)/vendor/' | \tr '\n' ',')$$pkg \-covermode=$(COVERAGE_MODE) \-coverprofile="$(COVERAGE_DIR)/coverage/`echo $$pkg | tr "/" "-"`.cover" $$pkg ;\done$Q $(GOCOVMERGE) $(COVERAGE_DIR)/coverage/*.cover > $(COVERAGE_PROFILE)$Q $(GO) tool cover -html=$(COVERAGE_PROFILE) -o $(COVERAGE_HTML)$Q $(GOCOV) convert $(COVERAGE_PROFILE) | $(GOCOVXML) > $(COVERAGE_XML).PHONY: lintlint: vendor | $(BASE) $(GOLINT) ; $(info $(M) running golint…) @ ## Run golint$Q cd $(BASE) && ret=0 && for pkg in $(PKGS); do \test -z "$$($(GOLINT) $$pkg | tee /dev/stderr)" || ret=1 ; \done ; exit $$ret.PHONY: fmtfmt: ; $(info $(M) running gofmt…) @ ## Run gofmt on all source files@ret=0 && for d in $$($(GO) list -f '{{.Dir}}' ./... | grep -v /vendor/); do \$(GOFMT) -l -w $$d/*.go || ret=$$? ; \done ; exit $$ret# Dependency managementvendor: Gopkg.toml Gopkg.lock | $(BASE) $(GODEP) ; $(info $(M) retrieving dependencies…)$Q cd $(BASE) && $(GODEP) ensure@ln -nsf . vendor/src@touch $@.PHONY: vendor-updatevendor-update: vendor | $(BASE) $(GODEP)ifeq "$(origin PKG)" "command line"$(info $(M) updating $(PKG) dependency…)$Q cd $(BASE) && $(GODEP) ensure -update $(PKG)else$(info $(M) updating all dependencies…)$Q cd $(BASE) && $(GODEP) ensure -updateendif@ln -nsf . vendor/src@touch vendor# Misc.PHONY: cleanclean: ; $(info $(M) cleaning…) @ ## Cleanup everything@rm -rf $(GOPATH)@rm -rf bin@rm -rf test/tests.* test/coverage.*# $(MAKEFILE_LIST) 表示# grep -E 将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式。# RS是记录分割符: 表示 \n 符号 awk '{print $0}' test1 //awk 'BEGIN{RS="\n"};{print $0}' test1 这二个是一样的# FS是指定列分隔符# printf "\033[36m%-15s\033[0m %s\n", $$1, $$2 其中的 - 表示左对齐为15和字符 $$1 表示分割出来第一段 $$2 表示分割出来第二段.PHONY: helphelp:@grep -E '^[ a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'.PHONY: versionversion:@echo $(VERSION)
支付宝 微信