.PHONY: build clean test fmt vet lint help gen-proto gen-proto-go gen-proto-py mod-tidy mod-vendor build-conch-init-initramfs
PROJECT_NAME := Conch
GOCMD := go
GOBUILD := $(GOCMD) build
GOCLEAN := $(GOCMD) clean
GOTEST := $(GOCMD) test
GOGET := $(GOCMD) get
GOMOD := $(GOCMD) mod
BIN_DIR := bin
VERSION_PKG := github.com/openeuler/Conch/internal/version
VERSION_TAG ?= $(shell git describe --tags --abbrev=0 2>/dev/null || echo unknown)
GIT_COMMIT ?= $(shell git rev-parse --short=8 HEAD 2>/dev/null || echo unknown)
VERSION_LDFLAGS := -X $(VERSION_PKG).Version=$(VERSION_TAG) -X $(VERSION_PKG).Commit=$(GIT_COMMIT)
CONCH_PROTO_DIR := ./api
CONCH_GO_PROTO_DIR := ./api/go_proto
CONCH_PY_PROTO_DIR := ./api/py_proto
CLEANSCRIPT := ./scripts/cleancode.sh
CMDS := $(shell find cmd -mindepth 1 -maxdepth 1 -type d ! -name conch-unpack -exec basename {} \;)
export GO111MODULE=on
export PATH := $(shell go env GOPATH)/bin:$(PATH)
default: build
help: ## Show this help message
@echo "available commands:"
@grep -E '^[a-zA-Z_-]+:.*?
gen-proto: gen-proto-go gen-proto-py ## Generate Go and Python protobuf code
gen-proto-go: ## Generate Go protobuf code
@echo "installing proto tools (if not exist)..."
@which protoc >/dev/null 2>&1 || { echo "protoc is required; please install protobuf-compiler"; exit 1; }
@which protoc-gen-go >/dev/null 2>&1 || GOBIN=$(shell go env GOPATH)/bin go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11
@which protoc-gen-connect-go >/dev/null 2>&1 || GOBIN=$(shell go env GOPATH)/bin go install connectrpc.com/connect/cmd/protoc-gen-connect-go@v1.20.0
@gopath_bin="$$(go env GOPATH)/bin"; \
case ":$$PATH:" in \
*":$$gopath_bin:"*) ;; \
*) \
echo "GOPATH/bin is not in PATH; copying proto tools to /usr/bin..."; \
cp_cmd=cp; \
[ -w /usr/bin ] || cp_cmd="sudo cp"; \
[ -x "$$gopath_bin/protoc-gen-go" ] && $$cp_cmd "$$gopath_bin/protoc-gen-go" /usr/bin/protoc-gen-go; \
[ -x "$$gopath_bin/protoc-gen-connect-go" ] && $$cp_cmd "$$gopath_bin/protoc-gen-connect-go" /usr/bin/protoc-gen-connect-go; \
;; \
esac
@echo "generating Go proto code..."
@rm -rf $(CONCH_GO_PROTO_DIR)
@mkdir -p $(CONCH_GO_PROTO_DIR)
@protoc \
--proto_path=$(CONCH_PROTO_DIR) \
--go_out=$(CONCH_GO_PROTO_DIR) \
--go_opt=paths=source_relative \
--connect-go_out=$(CONCH_GO_PROTO_DIR) \
--connect-go_opt=paths=source_relative \
$(CONCH_PROTO_DIR)/*.proto;
@echo "Go proto code generated to $(CONCH_GO_PROTO_DIR)"
gen-proto-py: ## Generate Python protobuf and Connect client code
@echo "ensuring Python proto tools..."
@which protoc >/dev/null 2>&1 || { echo "protoc is required; please install protobuf-compiler"; exit 1; }
@which protoc-gen-connect-python >/dev/null 2>&1 || python3 -m pip install protoc-gen-connect-python==0.9.0
@echo "generating Python proto code..."
@rm -rf $(CONCH_PY_PROTO_DIR)
@mkdir -p $(CONCH_PY_PROTO_DIR)
@protoc \
--proto_path=$(CONCH_PROTO_DIR) \
--python_out=$(CONCH_PY_PROTO_DIR) \
--pyi_out=$(CONCH_PY_PROTO_DIR) \
--connect-python_out=$(CONCH_PY_PROTO_DIR) \
$(CONCH_PROTO_DIR)/agent.proto
@echo "Fixing Python Connect import..."
@python3 -c "import pathlib; p=pathlib.Path('$(CONCH_PY_PROTO_DIR)/agent_connect.py'); p.write_text(p.read_text().replace('import agent_pb2 as agent__pb2', 'from . import agent_pb2 as agent__pb2'))"
@python3 -c "import pathlib; pathlib.Path('$(CONCH_PY_PROTO_DIR)/__init__.py').write_text('# Auto-generated by Makefile gen-proto-py\nfrom . import agent_pb2, agent_connect\n')"
@echo "Python proto code generated to $(CONCH_PY_PROTO_DIR)"
build: ## Build all Conch binaries
@mkdir -p $(BIN_DIR)
@set -e; for cmd in $(CMDS); do \
echo "building $$cmd..."; \
$(GOBUILD) -ldflags "$(VERSION_LDFLAGS)" -o "$(BIN_DIR)/$$cmd" "./cmd/$$cmd"; \
done
build-offline:
@echo "syncing dependency manifests from image backup..."
@cp /go/go.mod.backup ./go.mod
@cp /go/go.sum.backup ./go.sum
@echo "building binaries using image cache..."
@mkdir -p $(BIN_DIR)
@for cmd in $(CMDS); do \
echo "building static cmd/$$cmd..."; \
CGO_ENABLED=0 GOOS=linux GOARCH=$$(go env GOARCH) \
$(GOBUILD) -mod=readonly -tags "netgo,osusergo" \
-ldflags '-s -w -extldflags "-static" $(VERSION_LDFLAGS)' \
-o $(BIN_DIR)/$$cmd ./cmd/$$cmd; \
done
@git checkout go.mod go.sum 2>/dev/null || true
build-%: ## Build specific binary (e.g., make build-conchd)
@echo "building cmd/$*..."
@mkdir -p $(BIN_DIR)
$(GOBUILD) -ldflags "$(VERSION_LDFLAGS)" -o $(BIN_DIR)/$* ./cmd/$*
build-conch-init-initramfs: ## Build minimal initramfs that runs conch-init as PID 1
@echo "building static conch-init for initramfs..."
@mkdir -p $(BIN_DIR)
CGO_ENABLED=0 GOOS=linux GOARCH=$$(go env GOARCH) \
$(GOBUILD) -tags "netgo,osusergo" \
-ldflags '-s -w -extldflags "-static"' -buildvcs=false \
-o $(BIN_DIR)/conch-init ./cmd/conch-init
./scripts/build-conch-init-initramfs.sh --init-bin "$(BIN_DIR)/conch-init"
clean: ## Clean build artifacts
@echo "cleaning build artifacts..."
$(GOCLEAN)
rm -rf $(BIN_DIR)
@echo "cleaning completed"
test: ## Run all tests
@echo "running tests..."
$(GOTEST) -v ./...
test-coverage: ## Run tests with coverage report
@echo "running tests and generating coverage report..."
$(GOTEST) -v -coverprofile=coverage.out ./...
$(GOCMD) tool cover -html=coverage.out -o coverage.html
@echo "coverage report generated: coverage.html"
fmt: cleancode ## Format code (go fmt + cleancode)
@echo "formatting code with go fmt..."
$(GOCMD) fmt ./...
@echo "code formatting completed"
vet: ## Run go vet
@echo "running go vet..."
$(GOCMD) vet ./...
lint: fmt vet ## Tidy go modules
mod-tidy: ## Tidy go modules
@echo "tidying dependencies..."
$(GOMOD) tidy
mod-vendor: ## Download dependencies to vendor directory
@echo "downloading dependencies to vendor directory..."
$(GOMOD) vendor
cleancode: ## Clean code (remove trailing spaces/CR)
@echo "cleaning code..."
@if [ ! -f $(CLEANSCRIPT) ]; then \
echo "Error: cleancode script not found at $(CLEANSCRIPT)"; \
exit 1; \
fi
@if [ ! -x $(CLEANSCRIPT) ]; then \
chmod +x $(CLEANSCRIPT); \
fi
@$(CLEANSCRIPT) > /dev/null 2>&1
@echo "code cleaning completed"