Skip to content

Instantly share code, notes, and snippets.

Created December 8, 2020 06:51
Show Gist options
  • Save alswl/b580a89ef851e736e04463c4b06446ba to your computer and use it in GitHub Desktop.
Save alswl/b580a89ef851e736e04463c4b06446ba to your computer and use it in GitHub Desktop.
general makefile for golang project, via
# Copyright 2019 The Caicloud Authors.
# The old school Makefile, following are required targets. The Makefile is written
# to allow building multiple binaries. You are free to add more targets or change
# existing implementations, as long as the semantics are preserved.
# make - default to 'build' target
# make lint - code analysis
# make test - run unit test (or plus integration test)
# make build - alias to build-local target
# make build-local - build local binary targets
# make build-linux - build linux binary targets
# make container - build containers
# $ docker login registry -u username -p xxxxx
# make push - push containers
# make clean - clean up targets
# Not included but recommended targets:
# make e2e-test
# The makefile is also responsible to populate project version information.
# Tweak the variables based on your project.
# This repo's root import path (under GOPATH).
# Target binaries. You can build multiple binaries for a single project.
TARGETS := admin controller
# Container image prefix and suffix added to targets.
# The final built images are:
# $[REGISTRY] is an item from $[REGISTRIES], $[TARGET] is an item from $[TARGETS].
IMAGE_PREFIX ?= $(strip template-)
IMAGE_SUFFIX ?= $(strip )
# Container registries.
# Container registry for base images.
# These variables should not need tweaking.
# It's necessary to set this because some environments don't link sh -> bash.
export SHELL := /bin/bash
# It's necessary to set the errexit flags for the bash shell.
export SHELLOPTS := errexit
# Project main package location (can be multiple ones).
CMD_DIR := ./cmd
# Project output directory.
OUTPUT_DIR := ./bin
# Build direcotory.
BUILD_DIR := ./build
# Current version of the project.
VERSION ?= $(shell git describe --tags --always --dirty)
# Available cpus for compiling, please refer to for more information.
CPUS ?= $(shell /bin/bash hack/
# Track code version with Docker Label.
DOCKER_LABELS ?= git-describe="$(shell date -u +v%Y%m%d)-$(shell git describe --tags --always --dirty)"
# Golang standard bin directory.
GOPATH ?= $(shell go env GOPATH)
BIN_DIR := $(GOPATH)/bin
GOLANGCI_LINT := $(BIN_DIR)/golangci-lint
# Default golang flags used in build and test
# -mod=vendor: force go to use the vendor files instead of using the `$GOPATH/pkg/mod`
# -p: the number of programs that can be run in parallel
# -count: run each test and benchmark 1 times. Set this flag to disable test cache
export GOFLAGS ?= -mod=vendor -p=$(CPUS) -count=1
# Define all targets. At least the following commands are required:
# All targets.
.PHONY: lint test build container push
build: build-local
# more info about `GOGC` env:
curl -sfL | sh -s -- -b $(BIN_DIR) v1.23.6
@go test -race -coverprofile=coverage.out ./...
@go tool cover -func coverage.out | tail -n 1 | awk '{ print "Total coverage: " $$3 }'
@for target in $(TARGETS); do \
go build -v -o $(OUTPUT_DIR)/$${target} \
-ldflags "-s -w -X $(ROOT)/pkg/version.VERSION=$(VERSION) \
-X $(ROOT)/pkg/version.REPOROOT=$(ROOT)" \
$(CMD_DIR)/$${target}; \
@docker run --rm -it \
-v $(PWD):/go/src/$(ROOT) \
-w /go/src/$(ROOT) \
-e GOOS=linux \
-e GOARCH=amd64 \
-e GOPATH=/go \
$(BASE_REGISTRY)/golang:1.13-security \
/bin/bash -c 'for target in $(TARGETS); do \
go build -v -o $(OUTPUT_DIR)/$${target} \
-ldflags "-s -w -X $(ROOT)/pkg/version.VERSION=$(VERSION) \
-X $(ROOT)/pkg/version.REPOROOT=$(ROOT)" \
$(CMD_DIR)/$${target}; \
container: build-linux
@for target in $(TARGETS); do \
image=$(IMAGE_PREFIX)$${target}$(IMAGE_SUFFIX); \
docker build -t $(REGISTRY)/$${image}:$(VERSION) \
--label $(DOCKER_LABELS) \
-f $(BUILD_DIR)/$${target}/Dockerfile .; \
push: container
@for target in $(TARGETS); do \
image=$(IMAGE_PREFIX)$${target}$(IMAGE_SUFFIX); \
docker push $(REGISTRY)/$${image}:$(VERSION); \
.PHONY: clean
@-rm -vrf ${OUTPUT_DIR}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment