diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d280e8b9..b45c62f5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,3 +24,4 @@ jobs: run: | touch spec.md # Ensure its timestamp is newer than any generated files make + git diff --exit-code || (echo "Generated files are out of date. Please run 'make' and commit the changes." && exit 1) diff --git a/Makefile b/Makefile index 86a12c2d..02e4ad1d 100644 --- a/Makefile +++ b/Makefile @@ -4,43 +4,22 @@ CSI_SPEC := spec.md CSI_PROTO := csi.proto ## Build go language bindings CSI_A := csi.a -CSI_GO := lib/go/csi/csi.pb.go CSI_PKG := lib/go/csi -# This is the target for building the temporary CSI protobuf file. -# -# The temporary file is not versioned, and thus will always be -# built on GitHub Actions. -$(CSI_PROTO).tmp: $(CSI_SPEC) Makefile - echo "// Code generated by make; DO NOT EDIT." > "$@" - cat $< | sed -n -e '/```protobuf$$/,/^```$$/ p' | sed '/^```/d' >> "$@" - # This is the target for building the CSI protobuf file. -# -# This target depends on its temp file, which is not versioned. -# Therefore when built on GitHub Actions the temp file will always -# be built and trigger this target. On GitHub Actions the temp file -# is compared with the real file, and if they differ the build -# will fail. -# -# Locally the temp file is simply copied over the real file. -$(CSI_PROTO): $(CSI_PROTO).tmp -ifeq (true,$(GITHUB_ACTIONS)) - diff "$@" "$?" -else - cp -f "$?" "$@" -endif +$(CSI_PROTO): $(CSI_SPEC) Makefile + echo "// Code generated by make; DO NOT EDIT." > "$@" + sed -n -e '/```protobuf$$/,/^```$$/ {//!p;}' $< >> "$@" build: check build_cpp build_go build_cpp: $(MAKE) -C lib/cxx -# The file exists, but could be out-of-date. -$(CSI_GO): $(CSI_PROTO) - $(MAKE) -C lib/go csi/csi.pb.go +$(CSI_PKG)/%.pb.go: $(CSI_PROTO) + $(MAKE) -C lib/go -$(CSI_A): $(CSI_GO) +$(CSI_A): $(CSI_PKG)/*.go go mod download go install ./$(CSI_PKG) go build -o "$@" ./$(CSI_PKG) @@ -53,10 +32,10 @@ clean: clobber: clean $(MAKE) -C lib/go $@ - rm -f $(CSI_PROTO) $(CSI_PROTO).tmp + rm -f $(CSI_PROTO) # check generated files for violation of standards check: $(CSI_PROTO) awk '{ if (length > 72) print NR, $$0 }' $? | diff - /dev/null -.PHONY: clean clobber check csi_go build_go build_cpp +.PHONY: clean clobber check build_go build_cpp diff --git a/lib/go/Makefile b/lib/go/Makefile index 4a43cddc..0541c6d1 100644 --- a/lib/go/Makefile +++ b/lib/go/Makefile @@ -41,22 +41,24 @@ else ifeq (arm64,$(PROTOC_ARCH)) PROTOC_ARCH := aarch_64 endif -PROTOC := ./protoc PROTOC_ZIP := protoc-$(PROTOC_VER)-$(PROTOC_OS)-$(PROTOC_ARCH).zip PROTOC_URL := https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VER)/$(PROTOC_ZIP) PROTOC_TMP_DIR := .protoc -PROTOC_TMP_BIN := $(PROTOC_TMP_DIR)/bin/protoc +PROTOC := $(PROTOC_TMP_DIR)/bin/protoc + +$(GOBIN)/protoc-gen-go: ../../go.mod + go install google.golang.org/protobuf/cmd/protoc-gen-go +$(GOBIN)/protoc-gen-go-grpc: + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 $(PROTOC): - -go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.32.0 && \ - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 && \ - mkdir -p "$(PROTOC_TMP_DIR)" && \ + -mkdir -p "$(PROTOC_TMP_DIR)" && \ curl -L $(PROTOC_URL) -o "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" && \ unzip "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" -d "$(PROTOC_TMP_DIR)" && \ - chmod 0755 "$(PROTOC_TMP_BIN)" && \ - cp -f "$(PROTOC_TMP_BIN)" "$@" + chmod 0755 "$@" stat "$@" > /dev/null 2>&1 +PROTOC_ALL := $(GOBIN)/protoc-gen-go $(GOBIN)/protoc-gen-go-grpc $(PROTOC) ######################################################################## ## PATH ## @@ -71,49 +73,24 @@ export PATH := $(GOBIN):$(PATH) ## BUILD ## ######################################################################## CSI_PROTO := ../../csi.proto -CSI_PKG_ROOT := github.com/container-storage-interface/spec -CSI_PKG_SUB := $(shell cat $(CSI_PROTO) | sed -nE -e 's/^package.([^;]*).v[0-9]+;$$/\1/p'|tr '.' '/') -CSI_BUILD := $(CSI_PKG_SUB)/.build +CSI_PKG_SUB := csi CSI_GO := $(CSI_PKG_SUB)/csi.pb.go CSI_GRPC := $(CSI_PKG_SUB)/csi_grpc.pb.go -CSI_GRPC_TMP := $(CSI_BUILD)/$(CSI_PKG_ROOT)/lib/go/$(CSI_PKG_SUB)/csi_grpc.pb.go -CSI_GO_TMP := $(CSI_BUILD)/$(CSI_PKG_ROOT)/lib/go/$(CSI_PKG_SUB)/csi.pb.go -# This recipe generates the go language bindings to a temp area. -$(CSI_GO_TMP) $(CSI_GRPC_TMP): INCLUDE := -I../.. -I$(PROTOC_TMP_DIR)/include -$(CSI_GO_TMP) $(CSI_GRPC_TMP): $(CSI_PROTO) | $(PROTOC) +# This recipe generates the go language bindings +$(CSI_GO) $(CSI_GRPC): $(CSI_PROTO) $(PROTOC_ALL) @mkdir -p "$(@D)" - $(PROTOC) $(INCLUDE) --go-grpc_out=$(CSI_BUILD) --go_out=$(CSI_BUILD) \ - --go_opt=Mgoogle/protobuf/descriptor.proto=google.golang.org/protobuf/types/descriptorpb \ - --go_opt=Mgoogle/protobuf/wrappers.proto=google.golang.org/protobuf/types/known/wrapperspb \ + $(PROTOC) -I../.. --go-grpc_out=$(CSI_PKG_SUB) --go_out=$(CSI_PKG_SUB) \ + --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative \ "$( /dev/null 2>&1 || cp -f "$?" "$@" -endif -$(CSI_GRPC): $(CSI_GRPC_TMP) -ifeq (true,$(GITHUB_ACTIONS)) - diff "$@" "$?" -else - @mkdir -p "$(@D)" - diff "$@" "$?" > /dev/null 2>&1 || cp -f "$?" "$@" -endif - - build: $(CSI_GO) $(CSI_GRPC) clean: go clean -i ./... - rm -rf "$(CSI_GO)" "$(CSI_GRPC)" "$(CSI_BUILD)" + rm -rf "$(CSI_PKG_SUB)" clobber: clean - rm -fr "$(PROTOC)" "$(CSI_PKG_SUB)" + rm -fr "$(PROTOC_TMP_DIR)" .PHONY: clean clobber