golang.mk 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. # Copyright 2016 The Rook Authors. All rights reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ====================================================================================
  15. # Makefile helper functions for golang
  16. #
  17. ifeq ($(GO_PROJECT),)
  18. $(error the variable GO_PROJECT must be set prior to including golang.mk)
  19. endif
  20. # These targets will be statically linked.
  21. GO_STATIC_PACKAGES ?=
  22. ifeq ($(GO_STATIC_PACKAGES),)
  23. $(error please set GO_STATIC_PACKAGES prior to including golang.mk)
  24. endif
  25. # These are the static test packages
  26. GO_STATIC_PACKAGES ?=
  27. # Optional. These are subdirs that we look for all go files to test, vet, and fmt
  28. GO_SUBDIRS ?= cmd pkg
  29. # Optional. Additional subdirs used for integration or e2e testings
  30. GO_INTEGRATION_TESTS_SUBDIRS ?= tests
  31. # Optional directories (relative to CURDIR)
  32. GO_PKG_DIR ?= $(WORK_DIR)/pkg
  33. # Optional build flags passed to go tools
  34. GO_BUILDFLAGS ?=
  35. GO_LDFLAGS ?=
  36. GO_TAGS ?=
  37. GO_TEST_FLAGS ?=
  38. # ====================================================================================
  39. # Setup go environment
  40. GO_SUPPORTED_VERSIONS ?= 1.21|1.20
  41. GO_PACKAGES := $(foreach t,$(GO_SUBDIRS),$(GO_PROJECT)/$(t)/...)
  42. GO_INTEGRATION_TEST_PACKAGES := $(foreach t,$(GO_INTEGRATION_TESTS_SUBDIRS),$(GO_PROJECT)/$(t)/integration)
  43. ifneq ($(GO_TEST_SUITE),)
  44. GO_TEST_FLAGS += -run '$(GO_TEST_SUITE)'
  45. endif
  46. ifneq ($(GO_TEST_FILTER),)
  47. TEST_FILTER_PARAM := -testify.m '$(GO_TEST_FILTER)'
  48. endif
  49. GOPATH := $(shell go env GOPATH)
  50. # setup tools used during the build
  51. GOLINT := $(TOOLS_HOST_DIR)/golint
  52. GOJUNIT := $(TOOLS_DIR)/go-junit-report
  53. GO := go
  54. GOHOST := GOOS=$(GOHOSTOS) GOARCH=$(GOHOSTARCH) go
  55. GO_VERSION := $(shell $(GO) version | sed -ne 's/[^0-9]*\(\([0-9]\.\)\{0,4\}[0-9][^.]\).*/\1/p')
  56. GO_FULL_VERSION := $(shell $(GO) version)
  57. GOFMT_VERSION := $(GO_VERSION)
  58. ifneq ($(findstring $(GOFMT_VERSION),$(GO_VERSION)),)
  59. GOFMT := $(shell which gofmt)
  60. else
  61. GOFMT := $(TOOLS_HOST_DIR)/gofmt$(GOFMT_VERSION)
  62. endif
  63. GO_OUT_DIR := $(abspath $(OUTPUT_DIR)/bin/$(PLATFORM))
  64. GO_TEST_OUTPUT := $(abspath $(OUTPUT_DIR)/tests/$(PLATFORM))
  65. ifeq ($(GOOS),windows)
  66. GO_OUT_EXT := .exe
  67. endif
  68. # NOTE: the install suffixes are matched with the build container to speed up the
  69. # the build. Please keep them in sync.
  70. ifneq ($(GO_PKG_DIR),)
  71. GO_PKG_BASE_DIR := $(abspath $(GO_PKG_DIR)/$(PLATFORM))
  72. GO_PKG_STATIC_FLAGS := -pkgdir $(GO_PKG_BASE_DIR)_static
  73. endif
  74. GO_COMMON_FLAGS = $(GO_BUILDFLAGS) -tags '$(GO_TAGS)'
  75. GO_STATIC_FLAGS = $(GO_COMMON_FLAGS) $(GO_PKG_STATIC_FLAGS) -installsuffix static -ldflags '$(GO_LDFLAGS)'
  76. # ====================================================================================
  77. # Targets
  78. ifeq ($(filter help clean distclean prune go.clean, $(MAKECMDGOALS)),)
  79. .PHONY: go.check
  80. go.check:
  81. ifneq ($(shell $(GO) version | grep -q -E '\bgo($(GO_SUPPORTED_VERSIONS))\b' && echo 0 || echo 1), 0)
  82. $(error unsupported: $(GO_FULL_VERSION). Please make install one of the following supported version: '$(GO_SUPPORTED_VERSIONS)')
  83. endif
  84. -include go.check
  85. endif
  86. .PHONY: go.init
  87. go.init:
  88. @:
  89. .PHONY: go.build
  90. go.build:
  91. @echo === go build $(PLATFORM)
  92. $(info Go version: $(shell $(GO) version))
  93. $(foreach p,$(GO_STATIC_PACKAGES),@CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GO) build -v -o $(GO_OUT_DIR)/$(lastword $(subst /, ,$(p)))$(GO_OUT_EXT) $(GO_STATIC_FLAGS) $(p)${\n})
  94. $(foreach p,$(GO_TEST_PACKAGES),@CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GO) test -v -c -o $(GO_TEST_OUTPUT)/$(lastword $(subst /, ,$(p)))$(GO_OUT_EXT) $(GO_STATIC_FLAGS) $(p)${\n})
  95. .PHONY: go.install
  96. go.install:
  97. @echo === go install $(PLATFORM)
  98. $(foreach p,$(GO_STATIC_PACKAGES),@CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GO) install -v $(GO_STATIC_FLAGS) $(p)${\n})
  99. # GOJUNIT need to happen in order and NOT in parallel, so call them explicitly
  100. .PHONY: go.test.unit
  101. go.test.unit:
  102. @$(MAKE) $(GOJUNIT)
  103. @echo === go test unit-tests
  104. @mkdir -p $(GO_TEST_OUTPUT)
  105. CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GOHOST) test -v -cover $(GO_STATIC_FLAGS) $(GO_PACKAGES)
  106. CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GOHOST) test -v -cover $(GO_TEST_FLAGS) $(GO_STATIC_FLAGS) $(GO_PACKAGES) 2>&1 | tee $(GO_TEST_OUTPUT)/unit-tests.log
  107. @cat $(GO_TEST_OUTPUT)/unit-tests.log | $(GOJUNIT) -set-exit-code > $(GO_TEST_OUTPUT)/unit-tests.xml
  108. .PHONY:
  109. go.test.integration: $(GOJUNIT)
  110. @echo === go test integration-tests
  111. @mkdir -p $(GO_TEST_OUTPUT)
  112. CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GOHOST) test -v -i $(GO_STATIC_FLAGS) $(GO_INTEGRATION_TEST_PACKAGES)
  113. CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GOHOST) test -v -timeout 7200s $(GO_TEST_FLAGS) $(GO_STATIC_FLAGS) $(GO_INTEGRATION_TEST_PACKAGES) $(TEST_FILTER_PARAM) 2>&1 | tee $(GO_TEST_OUTPUT)/integration-tests.log
  114. @cat $(GO_TEST_OUTPUT)/integration-tests.log | $(GOJUNIT) -set-exit-code > $(GO_TEST_OUTPUT)/integration-tests.xml
  115. .PHONY: go.lint
  116. go.lint: $(GOLINT)
  117. @echo === go lint
  118. @$(GOLINT) -set_exit_status=true $(GO_PACKAGES) $(GO_INTEGRATION_TEST_PACKAGES)
  119. .PHONY: go.vet
  120. go.vet:
  121. @echo === go vet
  122. CGO_ENABLED=$(CGO_ENABLED_VALUE) $(GOHOST) vet $(GO_COMMON_FLAGS) $(GO_PACKAGES) $(GO_INTEGRATION_TEST_PACKAGES)
  123. .PHONY: go.fmt
  124. # ignore deepcopy generated files since the tool hardcoded the header with a "// +build" which in Golang 1.17 makes it fail gofmt since "////go:build" is preferred
  125. # see: https://github.com/kubernetes/gengo/blob/master/examples/deepcopy-gen/generators/deepcopy.go#L136
  126. # https://github.com/kubernetes/gengo/pull/210
  127. go.fmt: $(GOFMT)
  128. @gofmt_out=$$(find $(GO_SUBDIRS) -name "*.go" -not -name "*.deepcopy.go" | xargs $(GOFMT) -s -d -e 2>&1) && [ -z "$${gofmt_out}" ] || (echo "$${gofmt_out}" 1>&2; exit 1)
  129. go.validate: go.vet go.fmt
  130. .PHONY: go.mod.update
  131. go.mod.update:
  132. @echo === updating modules
  133. @$(GOHOST) get -u ./...
  134. .PHONY: go.mod.check
  135. go.mod.check:
  136. @echo === syncing root modules with APIs modules
  137. @cp -a go.sum pkg/apis/go.sum
  138. @cat go.mod | sed -e 's|^module github.com/rook/rook|module github.com/rook/rook/pkg/apis|' \
  139. -e '\:^replace github.com/rook/rook/pkg/apis => ./pkg/apis:d' > pkg/apis/go.mod
  140. @echo === ensuring APIs modules are tidied
  141. @(cd pkg/apis/; $(GOHOST) mod tidy -compat=$(GO_VERSION))
  142. @echo === ensuring root modules are tidied
  143. @$(GOHOST) mod tidy -compat=$(GO_VERSION)
  144. .PHONY: go.mod.clean
  145. go.mod.clean:
  146. @echo === cleaning modules cache
  147. @sudo rm -fr $(WORK_DIR)/cross_pkg
  148. @$(GOHOST) clean -modcache
  149. $(GOLINT):
  150. @echo === installing golint
  151. @mkdir -p $(TOOLS_HOST_DIR)/tmp
  152. @GOPATH=$(TOOLS_HOST_DIR)/tmp GOBIN=$(TOOLS_HOST_DIR) $(GOHOST) get github.com/golang/lint/golint
  153. @rm -fr $(TOOLS_HOST_DIR)/tmp
  154. $(GOFMT):
  155. @echo === installing gofmt$(GOFMT_VERSION)
  156. @mkdir -p $(TOOLS_HOST_DIR)/tmp
  157. @curl -sL https://dl.google.com/go/go$(GOFMT_VERSION).$(shell go env GOHOSTOS)-$(GOHOSTARCH).tar.gz | tar -xz -C $(TOOLS_HOST_DIR)/tmp
  158. @mv $(TOOLS_HOST_DIR)/tmp/go/bin/gofmt $(GOFMT)
  159. @rm -fr $(TOOLS_HOST_DIR)/tmp
  160. $(GOJUNIT):
  161. @echo === installing go-junit-report
  162. @mkdir -p $(TOOLS_DIR)/tmp
  163. @curl -sL https://github.com/jstemmer/go-junit-report/releases/download/v2.0.0/go-junit-report-v2.0.0-$(GOOS)-$(GOHOSTARCH).tar.gz | tar -xz -C $(TOOLS_DIR)/tmp
  164. @mv $(TOOLS_DIR)/tmp/go-junit-report $(TOOLS_DIR)
  165. @rm -fr $(TOOLS_DIR)/tmp
  166. export CONTROLLER_GEN=$(TOOLS_HOST_DIR)/controller-gen-$(CONTROLLER_GEN_VERSION)
  167. $(CONTROLLER_GEN):
  168. { \
  169. set -e ;\
  170. mkdir -p $(TOOLS_HOST_DIR) ;\
  171. CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
  172. cd $$CONTROLLER_GEN_TMP_DIR ;\
  173. go mod init tmp;\
  174. unset GOOS GOARCH ;\
  175. export CGO_ENABLED=$(CGO_ENABLED_VALUE) ;\
  176. export GOBIN=$$CONTROLLER_GEN_TMP_DIR ;\
  177. echo === installing controller-gen ;\
  178. go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION);\
  179. mv $$CONTROLLER_GEN_TMP_DIR/controller-gen $(CONTROLLER_GEN) ;\
  180. rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
  181. }
  182. YQ_VERSION = v4.14.2
  183. YQ := $(TOOLS_HOST_DIR)/yq-$(YQ_VERSION)
  184. export YQ
  185. $(YQ):
  186. @echo === installing yq $(YQ_VERSION) $(REAL_HOST_PLATFORM)
  187. @mkdir -p $(TOOLS_HOST_DIR)
  188. @curl -JL https://github.com/mikefarah/yq/releases/download/$(YQ_VERSION)/yq_$(REAL_HOST_PLATFORM) -o $(YQ)
  189. @chmod +x $(YQ)
  190. export CODE_GENERATOR_VERSION=0.20.0
  191. export CODE_GENERATOR=$(TOOLS_HOST_DIR)/code-generator-$(CODE_GENERATOR_VERSION)
  192. $(CODE_GENERATOR):
  193. mkdir -p $(TOOLS_HOST_DIR)
  194. curl -sL https://github.com/kubernetes/code-generator/archive/refs/tags/v${CODE_GENERATOR_VERSION}.tar.gz | tar -xz -C $(TOOLS_HOST_DIR)