Skip to content

Commit

Permalink
proto: update to latest grpc protobuf gen tools
Browse files Browse the repository at this point in the history
Modeled after:
container-storage-interface/spec#552

Update to the latest, non-deprecated versions of Google's tools for
protobuf generation.

Also update make tools to allow working with go modules outside of
GOPATH, and to build on ARM-based Macbooks.

New tools are significantly different from prior tools. Notably, the
grpc plugin is no longer supported, so the `--go-gprc_out` flag is used,
which moves some generated content from `cosi.pb.go` to a new
`cosi_grpc.pb.go` file.

We are still able to keep fake-gen by continuing to use deprecated tool
versions for that purpose. There's a chance that it may not serve the
COSI project long-term, but it should still work for now.

Signed-off-by: Blaine Gardner <[email protected]>
  • Loading branch information
BlaineEXE committed Jul 18, 2024
1 parent eb40da2 commit 3c319fe
Show file tree
Hide file tree
Showing 10 changed files with 809 additions and 886 deletions.
3 changes: 0 additions & 3 deletions proto/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
.DS_Store
.build
*.swp
cosi.proto.tmp
protoc*
cosi.a
.protoc
.idea
.project
226 changes: 58 additions & 168 deletions proto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export GOPATH

# Only set PROTOC_VER if it has an empty value.
ifeq (,$(strip $(PROTOC_VER)))
PROTOC_VER := 3.14.0
PROTOC_VER := 27.2
endif

PROTOC_OS := $(shell uname -s)
Expand All @@ -36,98 +36,30 @@ 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
PROTOC_TMP_INC := $(PROTOC_TMP_DIR)/include

$(PROTOC):
-mkdir -p "$(PROTOC_TMP_DIR)" && \
curl -L $(PROTOC_URL) -o "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" && \
unzip -o "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" -d "$(PROTOC_TMP_DIR)" && \
unzip -o "$(PROTOC_TMP_DIR)/$(PROTOC_ZIP)" -d "$(PROTOC_TMP_INC)/*" && \
chmod 0755 "$(PROTOC_TMP_BIN)" && \
cp -f "$(PROTOC_TMP_BIN)" "$@"
chmod 0755 "$@"
stat "$@" > /dev/null 2>&1

$(GOBIN)/protoc-gen-go: go.mod
go install google.golang.org/protobuf/cmd/protoc-gen-go

########################################################################
## PROTOC-GEN-GO ##
########################################################################

# This is the recipe for getting and installing the go plug-in
# for protoc
PROTOC_GEN_GO_PKG := github.com/golang/protobuf/protoc-gen-go
PROTOC_GEN_GO := protoc-gen-go
$(PROTOC_GEN_GO): PROTOBUF_PKG := $(dir $(PROTOC_GEN_GO_PKG))
$(PROTOC_GEN_GO): PROTOBUF_VERSION := v1.3.2
$(PROTOC_GEN_GO):
mkdir -p $(dir $(GOPATH)/src/$(PROTOBUF_PKG))
test -d $(GOPATH)/src/$(PROTOBUF_PKG)/.git || git clone https://$(PROTOBUF_PKG) $(GOPATH)/src/$(PROTOBUF_PKG)
(cd $(GOPATH)/src/$(PROTOBUF_PKG) && \
(test "$$(git describe --tags | head -1)" = "$(PROTOBUF_VERSION)" || \
(git fetch && git checkout tags/$(PROTOBUF_VERSION))))
(cd $(GOPATH)/src/$(PROTOBUF_PKG) && go get -v -d $$(go list -f '{{ .ImportPath }}' ./...)) && \
go build -o "$@" $(PROTOC_GEN_GO_PKG)
$(GOBIN)/protoc-gen-go-grpc:
go install google.golang.org/grpc/cmd/[email protected]

$(GOBIN)/protoc-gen-go-json:
go install github.com/mitchellh/[email protected]

########################################################################
## PROTOC-GEN-GO-JSON ##
########################################################################

# This is the recipe for getting and installing the json plug-in
# for protoc-gen-go
PROTOC_GEN_GO_JSON_PKG := github.com/mitchellh/protoc-gen-go-json
PROTOC_GEN_GO_JSON := protoc-gen-go-json
$(PROTOC_GEN_GO_JSON): PROTOC_GEN_GO_JSON_VERSION := v1.1.0
$(PROTOC_GEN_GO_JSON):
mkdir -p $(dir $(GOPATH)/src/$(PROTOC_GEN_GO_JSON_PKG))
test -d $(GOPATH)/src/$(PROTOC_GEN_GO_JSON_PKG)/.git || git clone https://$(PROTOC_GEN_GO_JSON_PKG) $(GOPATH)/src/$(PROTOC_GEN_GO_JSON_PKG)
(cd $(GOPATH)/src/$(PROTOC_GEN_GO_JSON_PKG) && \
(test "$$(git describe --tags | head -1)" = "$(PROTOC_GEN_GO_JSON_VERSION)" || \
(git fetch && git checkout tags/$(PROTOC_GEN_GO_JSON_VERSION))))
(cd $(GOPATH)/src/$(PROTOC_GEN_GO_JSON_PKG) && go get -v -d $$(go list -f '{{ .ImportPath }}' ./...)) && \
go build -o "$@" $(PROTOC_GEN_GO_JSON_PKG)


########################################################################
## GEN-PROTO-GO ##
########################################################################

# This is the recipe for getting and installing the gen-proto pkg
# This is a dependency of grpc-go and must be installed before
# installing grpc-go.
GENPROTO_GO_SRC := github.com/googleapis/go-genproto
GENPROTO_GO_PKG := google.golang.org/genproto
GENPROTO_BUILD_GO := genproto-build-go
$(GENPROTO_BUILD_GO): GENPROTO_VERSION := 24fa4b261c55da65468f2abfdae2b024eef27dfb
$(GENPROTO_BUILD_GO):
mkdir -p $(dir $(GOPATH)/src/$(GENPROTO_GO_PKG))
test -d $(GOPATH)/src/$(GENPROTO_GO_PKG)/.git || git clone https://$(GENPROTO_GO_SRC) $(GOPATH)/src/$(GENPROTO_GO_PKG)
(cd $(GOPATH)/src/$(GENPROTO_GO_PKG) && \
(git fetch && git checkout $(GENPROTO_VERSION)))
(cd $(GOPATH)/src/$(GENPROTO_GO_PKG) && go get -v -d $$(go list -f '{{ .ImportPath }}' ./...))


########################################################################
## GRPC-GO ##
########################################################################

# This is the recipe for getting and installing the grpc go
GRPC_GO_SRC := github.com/grpc/grpc-go
GRPC_GO_PKG := google.golang.org/grpc
GRPC_BUILD_GO := grpc-build-go
$(GRPC_BUILD_GO): GRPC_VERSION := v1.26.0
$(GRPC_BUILD_GO):
mkdir -p $(dir $(GOPATH)/src/$(GRPC_GO_PKG))
test -d $(GOPATH)/src/$(GRPC_GO_PKG)/.git || git clone https://$(GRPC_GO_SRC) $(GOPATH)/src/$(GRPC_GO_PKG)
(cd $(GOPATH)/src/$(GRPC_GO_PKG) && \
(test "$$(git describe --tags | head -1)" = "$(GRPC_VERSION)" || \
(git fetch && git checkout tags/$(GRPC_VERSION))))
(cd $(GOPATH)/src/$(GRPC_GO_PKG) && go get -v -d $$(go list -f '{{ .ImportPath }}' ./...) && \
go build -o "$@" $(GRPC_GO_PKG))
PROTOC_ALL := $(GOBIN)/protoc-gen-go $(GOBIN)/protoc-gen-go-grpc $(GOBIN)/protoc-gen-go-json $(PROTOC)


########################################################################
Expand All @@ -136,110 +68,68 @@ $(GRPC_BUILD_GO):

# This is the recipe for getting and installing the grpc go
PROTOC_GEN_GO_FAKE_SRC := ./hack/fake-gen
PROTOC_GEN_GO_FAKE := protoc-gen-gofake
PROTOC_GEN_GO_FAKE := $(PROTOC_TMP_DIR)/bin/protoc-gen-gofake
$(PROTOC_GEN_GO_FAKE):
go build -o $(PROTOC_GEN_GO_FAKE) $(PROTOC_GEN_GO_FAKE_SRC)


########################################################################
## PATH ##
########################################################################

# Update PATH with the current directory. This enables the protoc
# binary to discover the protoc-gen-go binary, built inside this
# directory.
export PATH := $(shell pwd):$(PATH)
# Update PATH to discover the protoc-gen-gofake binary
export PATH := $(PROTOC_TMP_DIR)/bin:$(PATH)


########################################################################
## BUILD ##
########################################################################
COSI_PROTO := ./cosi.proto
COSI_SPEC := spec.md
COSI_PKG_ROOT := sigs.k8s.io/container-object-storage-interface-spec
COSI_PKG_SUB := .
COSI_BUILD := $(COSI_PKG_SUB)/.build
COSI_GO := $(COSI_PKG_SUB)/cosi.pb.go
COSI_GO_JSON := $(COSI_PKG_SUB)/cosi.pb.json.go
COSI_GO_FAKE := $(COSI_PKG_SUB)/fake/cosi.pb.fake.go
COSI_A := cosi.a
COSI_GO_TMP := $(COSI_BUILD)/$(COSI_PKG_ROOT)/cosi.pb.go
COSI_GO_JSON_TMP := $(COSI_BUILD)/$(COSI_PKG_ROOT)/cosi.pb.json.go
COSI_GO_FAKE_TMP := $(COSI_BUILD)/fake/$(COSI_PKG_ROOT)/cosi.pb.fake.go

# This recipe generates the go language bindings to a temp area.
$(COSI_GO_TMP): HERE := $(shell pwd)
$(COSI_GO_TMP): PTYPES_PKG := github.com/golang/protobuf/ptypes
$(COSI_GO_TMP): GO_OUT := plugins=grpc
$(COSI_GO_TMP): GO_OUT := $(GO_OUT),Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor
$(COSI_GO_TMP): GO_OUT := $(GO_OUT),Mgoogle/protobuf/wrappers.proto=$(PTYPES_PKG)/wrappers
$(COSI_GO_TMP): GO_OUT := $(GO_OUT):"$(HERE)/$(COSI_BUILD)"
$(COSI_GO_TMP): GO_JSON_OUT := emit_defaults=true
$(COSI_GO_TMP): GO_JSON_OUT := $(GO_JSON_OUT):"$(HERE)/$(COSI_BUILD)"
$(COSI_GO_TMP): GO_FAKE_OUT := emit_defaults
$(COSI_GO_TMP): GO_FAKE_OUT := $(GO_FAKE_OUT),packagePath=sigs.k8s.io/container-object-storage-interface-spec
$(COSI_GO_TMP): GO_FAKE_OUT := $(GO_FAKE_OUT):"$(HERE)/$(COSI_BUILD)"/fake
$(COSI_GO_TMP): INCLUDE := -I$(GOPATH)/src -I$(HERE)/$(PROTOC_TMP_DIR)/include
$(COSI_GO_TMP): $(COSI_PROTO) | $(PROTOC) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_JSON) $(PROTOC_GEN_GO_FAKE)
@mkdir -p "$(@D)"
@mkdir -p "$(COSI_BUILD)/fake"
(cd "$(GOPATH)/src" && \
$(HERE)/$(PROTOC) $(INCLUDE) --go_out=$(GO_OUT) --go-json_out=$(GO_JSON_OUT) --gofake_out=$(GO_FAKE_OUT) "$(COSI_PKG_ROOT)/$(<F)")

# The temp language bindings are compared to the ones that are
# versioned. If they are different then it means the language
# bindings were not updated prior to being committed.
$(COSI_GO): $(COSI_GO_TMP)
ifeq (true,$(TRAVIS))
diff "$@" "$?"
else
@mkdir -p "$(@D)"
diff "$@" "$?" > /dev/null 2>&1 || cp -f "$?" "$@"
endif

# The temp language bindings are compared to the ones that are
# versioned. If they are different then it means the language
# bindings were not updated prior to being committed.
$(COSI_GO_JSON): $(COSI_GO_JSON_TMP)
ifeq (true,$(TRAVIS))
diff "$@" "$?"
else
@mkdir -p "$(@D)"
diff "$@" "$?" > /dev/null 2>&1 || cp -f "$?" "$@"
endif
COSI_PROTO := ./cosi.proto
COSI_GO := ./cosi.pb.go
COSI_GO_GRPC := ./cosi_grpc.pb.go
COSI_GO_JSON := ./cosi.pb.json.go
COSI_GO_FAKE := ./fake/cosi.pb.fake.go

# The temp language bindings are compared to the ones that are
# versioned. If they are different then it means the language
# bindings were not updated prior to being committed.
$(COSI_GO_FAKE): $(COSI_GO_FAKE_TMP)
ifeq (true,$(TRAVIS))
diff "$@" "$?"
else
@mkdir -p "$(@D)"
diff "$@" "$?" > /dev/null 2>&1 || cp -f "$?" "$@"
endif
BUILD_TMP_DIR := ./.build
BUILD_TMP_COSI_A := $(BUILD_TMP_DIR)/cosi.a
BUILD_PROTO_PATH := sigs.k8s.io/container-object-storage-interface-api/proto
BUILD_COSI_GO_TMP := $(BUILD_TMP_DIR)/$(BUILD_PROTO_PATH)/cosi.pb.go
BUILD_COSI_GO_GRPC_TMP := $(BUILD_TMP_DIR)/$(BUILD_PROTO_PATH)/cosi_grpc.pb.go
BUILD_COSI_GO_JSON_TMP := $(BUILD_TMP_DIR)/$(BUILD_PROTO_PATH)/cosi.pb.json.go
BUILD_COSI_GO_FAKE_TMP := $(BUILD_TMP_DIR)/fake/cosi.pb.fake.go

# This recipe builds the Go archive from the sources in three steps:
#
# 1. Go get any missing dependencies.
# 2. Cache the packages.
# 3. Build the archive file.
$(COSI_A): $(COSI_GO) $(COSI_GO_JSON) $(COSI_GO_FAKE) $(GENPROTO_BUILD_GO) $(GRPC_BUILD_GO)
go get -v -d ./...
go install ./$(COSI_PKG_SUB)
go build -o "$@" ./$(COSI_PKG_SUB)

generate:
GO_JSON_OPTS := emit_defaults=true

GO_FAKE_OPTS := emit_defaults
GO_FAKE_OPTS := $(GO_FAKE_OPTS),packagePath=sigs.k8s.io/container-object-storage-interface-api/proto

$(COSI_PROTO): $(COSI_SPEC)
echo "// Code generated by make; DO NOT EDIT." > "$(COSI_PROTO)"
cat $(COSI_SPEC) | sed -n -e '/```protobuf$$/,/^```$$/ p' | sed '/^```/d' >> "$(COSI_PROTO)"

build: generate $(COSI_A)

clean:
$(COSI_GO) $(COSI_GO_GRPC) $(COSI_GO_JSON) $(COSI_GO_FAKE): $(COSI_PROTO) $(PROTOC_ALL) $(PROTOC_GEN_GO_FAKE)
mkdir -p "$(BUILD_TMP_DIR)"
mkdir -p "$(BUILD_TMP_DIR)/fake"
$(PROTOC) -I. -I$(PROTOC_TMP_INC) \
--go_out=$(BUILD_TMP_DIR) \
--go-grpc_out=$(BUILD_TMP_DIR) \
--go-json_out=$(GO_JSON_OPTS):$(BUILD_TMP_DIR) \
--gofake_out=$(GO_FAKE_OPTS):$(BUILD_TMP_DIR)/fake \
"$(<F)"
cp -f $(BUILD_COSI_GO_TMP) $(COSI_GO)
cp -f $(BUILD_COSI_GO_GRPC_TMP) $(COSI_GO_GRPC)
cp -f $(BUILD_COSI_GO_JSON_TMP) $(COSI_GO_JSON)
cp -f $(BUILD_COSI_GO_FAKE_TMP) $(COSI_GO_FAKE)

$(BUILD_TMP_COSI_A): $(COSI_GO) $(COSI_GO_GRPC) $(COSI_GO_JSON) $(COSI_GO_FAKE)
go build -o "$@" ./.

generate: $(COSI_PROTO) ## Generate cosi.proto

build: generate $(BUILD_TMP_COSI_A) ## Generate protobuf files, and ensure they build

.PHONY: clean
clean: ## Clean all builds and generated files
go clean -i ./...
rm -rf "$(COSI_PROTO)" "$(COSI_A)" "$(COSI_GO)" "$(COSI_GO_JSON)" "$(COSI_BUILD)"

clobber: clean
rm -fr "$(PROTOC)" "$(PROTOC_TMP_DIR)" "$(PROTOC_GEN_GO)" "$(PROTOC_GEN_GO_JSON)" "$(PROTOC_GEN_GO_FAKE)"
rm -rf "$(BUILD_TMP_DIR)" "$(COSI_PROTO)" "$(COSI_GO)" "$(COSI_GO_GRPC)" "$(COSI_GO_JSON)" "$(COSI_GO_FAKE)"

.PHONY: clean clobber $(GRPC_BUILD_GO) $(GENPROTO_BUILD_GO)
.PHONY: clobber
clobber: clean ## Clean, and remove all cached tooling
rm -fr "$(PROTOC_TMP_DIR)"
Loading

0 comments on commit 3c319fe

Please sign in to comment.