使用makefile可以快捷管理和构建自己的go项目, 适用于linux远程开发等环境.
提供一个基础的makefile供开发使用.
大部分是针对常用指令的二次封装
Makefile
先展示文件内容, 之后讲解具体指令功能和实现
# -------------------------------------------------------------------------------
# Makefile for go project
# -------------------------------------------------------------------------------# -------------------------------------------------------------------------------
# variables
# -------------------------------------------------------------------------------
MAIN_FILE := main.goBIN_DIR := ./bin
APP := main # the name of the application# the name of the docker image
# DOCKER_IMAGE_NAME := docker-image-name-example# args
STATIC_ARGS := -ldflags='-extldflags "-static"'
RACE_ARGS := -race# this dir is for the test output when u run `test` cmd
TEST_OUTPUT_DIR := ./test_output# color code
GREEN_COLOR_CODE_HEAD := \033[32m
GREEN_COLOR_CODE_END := \033[0m
RED_COLOR_CODE_HEAD := \033[31m
RED_COLOR_CODE_END := \033[0m# -------------------------------------------------------------------------------
# commands
# -------------------------------------------------------------------------------# build the application
.PHONY: build
build:go build -o $(BIN_DIR)/$(APP) $(MAIN_FILE)# build the application statically
# you can use this if you want to run the application on a system without a C compiler
# if you use glibc, you can also use the static version of glibc(like musl)
.PHONY: build-static
build-static:go build $(STATIC_ARGS) -o $(BIN_DIR)/$(APP) $(MAIN_FILE)# build the application with docker
# u need to set the DOCKER_IMAGE_NAME variable
.PHONY: build-docker
build-docker:docker build -t $(DOCKER_IMAGE_NAME) .@$(show_info)"Docker image built successfully: $(GREEN_COLOR_CODE_HEAD)$(DOCKER_IMAGE_NAME)$(GREEN_COLOR_CODE_END)";# run the application with race detector
# use this cmd when u develop
.PHONY: run
run:go run $(RACE_ARGS) $(MAIN_FILE)# test application
# it will create a coverage.out file(for test coverage)
.PHONY: test
test:mkdir -p $(TEST_OUTPUT_DIR)go test -v -covermode=set -coverprofile=$(TEST_OUTPUT_DIR)/coverage.out ./...# show the test coverage
# it will create a coverage.html file from coverage.out
# so, u need to run `test` cmd first
.PHONY: test-coverage
test-coverage: testgo tool cover -html=$(TEST_OUTPUT_DIR)/coverage.out -o $(TEST_OUTPUT_DIR)/coverage.html@$(show_info)"Please open $(GREEN_COLOR_CODE_HEAD)$(TEST_OUTPUT_DIR)/coverage.html$(GREEN_COLOR_CODE_END) to see the test coverage"# clean the application
# it will remove the bin directory and the test output directory
.PHONY: clean
clean:go cleanrm -rf $(BIN_DIR) $(TEST_OUTPUT_DIR)# -------------------------------------------------------------------------------
# functions
# -------------------------------------------------------------------------------# echo time
TIMESTAMP_FORMAT := %Y-%m-%d %H:%M:%S
define timestamp$(shell date "+$(TIMESTAMP_FORMAT)")
endef# show info
INFO_PREFIX := *INFO
define show_info@echo -e "$(GREEN_COLOR_CODE_HEAD)$(INFO_PREFIX):$(GREEN_COLOR_CODE_END)"@echo -e $(1)
endef# show error
# it will exit the program
ERROR_PREFIX := *ERROR
define show_error@echo -e "$(RED_COLOR_CODE_HEAD)$(ERROR_PREFIX):$(RED_COLOR_CODE_END)"@echo -e $(1)exit 1
endef
- build: 基本构建指令, 最简单的编译二级制可执行文件的指令.
- build-static: 编译静态文件
- build-docker: 打包docker image
- run: 开发中测试代码
- test: 运行单元测试
- test-coverage: 使用HTML的方式展示单元测试的覆盖率
- clean: 清理
build
# build the application
.PHONY: build
build:go build -o $(BIN_DIR)/$(APP) $(MAIN_FILE)
最基础的go的编译运行的方式
- 编译出来的可执行文件在
bin
目录下
build-static
# build the application statically
# you can use this if you want to run the application on a system without a C compiler
# if you use glibc, you can also use the static version of glibc(like musl)
.PHONY: build-static
build-static:go build $(STATIC_ARGS) -o $(BIN_DIR)/$(APP) $(MAIN_FILE)
GO默认编译出来的就是静态的文件, 但是可能需要依赖C的库, 为了进一步的静态编译, 可以使用这个指令
在设置网络编程的时候, 可能存在glibc库无法编译进去, 可以使用musl版本的
build-docker
# build the application with docker
# u need to set the DOCKER_IMAGE_NAME variable
.PHONY: build-docker
build-docker:docker build -t $(DOCKER_IMAGE_NAME) .@$(show_info)"Docker image built successfully: $(GREEN_COLOR_CODE_HEAD)$(DOCKER_IMAGE_NAME)$(GREEN_COLOR_CODE_END)";
打包docker image, 需要自己在当前目录编写好dockerfile
- 需要自己设置好
DOCKER_IMAGE_NAME
配置的名字
运行成功之后会输出
Docker image built successfully: XXX
run
# run the application with race detector
# use this cmd when u develop
.PHONY: run
run:go run $(RACE_ARGS) $(MAIN_FILE)
在dev的时候运行程序, 带上-race
检查竞态
它可以帮助开发者检测并发程序中的数据竞争问题。数据竞争是指多个goroutine同时访问共享内存,并且至少有一个访问是写操作,而没有使用同步机制来保护共享数据,这会导致程序的行为变得不可预测,甚至崩溃。
test
# test application
# it will create a coverage.out file(for test coverage)
.PHONY: test
test:mkdir -p $(TEST_OUTPUT_DIR)go test -v -covermode=set -coverprofile=$(TEST_OUTPUT_DIR)/coverage.out ./...
执行单元测试
会创建一个用于单元测试输出的文件夹
输出的
coverage.out
文件说明了单元测试的覆盖率情况, 这一般使用百分比表示
效果:
.
└── test_output├── coverage.html└── coverage.out
test-coverage
# show the test coverage
# it will create a coverage.html file from coverage.out
# so, u need to run `test` cmd first
.PHONY: test-coverage
test-coverage: testgo tool cover -html=$(TEST_OUTPUT_DIR)/coverage.out -o $(TEST_OUTPUT_DIR)/coverage.html@$(show_info)"Please open $(GREEN_COLOR_CODE_HEAD)$(TEST_OUTPUT_DIR)/coverage.html$(GREEN_COLOR_CODE_END) to see the test coverage"
生成展示单元测试覆盖情况的HTML文件
可以在浏览器中打开并且查看效果
clean
# clean the application
# it will remove the bin directory and the test output directory
.PHONY: clean
clean:go cleanrm -rf $(BIN_DIR) $(TEST_OUTPUT_DIR)
清除文件
包含GO的编译文件和test输出文件
函数
# show info
INFO_PREFIX := *INFO
define show_info@echo -e "$(GREEN_COLOR_CODE_HEAD)$(INFO_PREFIX):$(GREEN_COLOR_CODE_END)"@echo -e $(1)
endef# show error
# it will exit the program
ERROR_PREFIX := *ERROR
define show_error@echo -e "$(RED_COLOR_CODE_HEAD)$(ERROR_PREFIX):$(RED_COLOR_CODE_END)"@echo -e $(1)exit 1
endef
一些函数帮助格式化输出一些tips内容
- 打印error message的时候会直接使用exit 1退出, 因为出现了错误