Makefile 看这一篇就够

Makefile 看这一篇就够

makefile 是一个文本文件,以下是一个子命令,包含:

  • 名称:支持英文、数字、连字符"-"和下划线 " _"
  • 注释:使用 "#" 表示注释,不支持 /*...*/。推荐写在名称的上一行
  • 命令:任何可在 shell 执行的命令行语句。必须是\t 开头,否则报错 make: Nothing to be done for 'build'.
  • .PHONY:可选,命令声明了 .PHONY,执行时将不会输出具体命令到终端。在一些 CI 工具中可以起到过滤敏感信息的作用。
.PHONY: build
# 编译构建
build:
	go build ./...

变量定义和使用

  • 可直接赋值,也可以执行 shell 赋值。
  • 使用变量的方法是 $(VARIABLE_NAME)。
ENV_GROUP = dev
# 获取最新tag
GIT_TAG=$(shell git tag|grep "v*.[0-9]$$"|sort -r --version-sort|head -n1)
APP_GIT_COMMIT_ID=$(shell git rev-parse --short=8 HEAD)

# 使用变量$(VARIABLE_NAME)
GIT_TAG_COMMIT = $(GIT_TAG)-$(APP_GIT_COMMIT_ID)

多文件

  • 使用 include 引入子文件
include ./scripts/develop.mk
include ./scripts/deploy-local.mk
  • 判断文件存在则引入
#文件存在, 则引入
ifneq ($(wildcard ../scripts/Makefile),)
    include ../scripts/Makefile
endif

if-else判断

可以使用 ifeq ifneq

ifeq ($(NAMESPACE), test-1)
    ENV_GROUP = test-a
else ifeq ($(NAMESPACE), test-2)
    ENV_GROUP = test-a
endif

可以使用在命令中

.PHONY: api
# 由 proto 生成接口层代码
api:
ifneq ($(PROTOC_GEN_GO_VERSION), v1.28.1)
	go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1
else
	echo "ok"
endif

相同变量名,为不同命令导入不同值

使用 export 关键词,为命令传值,可多次传值。


IMAGE_NAME=dockerimg
IMAGE_TAG=dev-1


.PHONY: deploy-test1
# 构建、推送测试环境 1
deploy-test1: export IMAGE_NAME = dockerimg-test
deploy-test1: export IMAGE_TAG = test-1
deploy-test1:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)
	make push

.PHONY: deploy-test2
# 构建、推送测试环境 1
deploy-test2: export IMAGE_NAME = dockerimg-test
deploy-test2: export IMAGE_TAG = test-2
deploy-test2:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)
	make push

从命令行传递变量

上述例子中,定义的变量可以放在shell命令行中,输入完 make 和命令后,追加上变量可以起到传递命令的作用。

IMAGE_NAME=dockerimg
IMAGE_TAG=dev-1

.PHONY: deploy-test
# 构建测试环境,使用方式make deploy-test IMAGE_NAME=img-test-1 IMAGE_TAG=test-1
deploy-test:
	docker build ./ -f ./Dockerfile -t $(IMAGE_NAME):$(IMAGE_TAG)

比如 make deploy-test IMAGE_NAME=img-test-1 IMAGE_TAG=test-1

打印输出所有命令

默认情况下,输入make 执行的是第一个命令,可以通过修改.DEFAULT_GOAL 修改动作。以下是一个 help 命令,输出所有带注释的 make 子命令。

# show help
help:
	@echo ''
	@echo 'Usage:'
	@echo ' make [target]'
	@echo ''
	@echo 'Targets:'
	@awk '/^[a-zA-Z\-\_0-9]+:/ { \
	helpMessage = match(lastLine, /^# (.*)/); \
	    if (helpMessage) { \
	        helpCommand = substr($$1, 0, index($$1, ":")-1); \
	        helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
	        printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
	    } \
	} \
	{ lastLine = $$0 }' $(MAKEFILE_LIST)
# 默认 help
.DEFAULT_GOAL := help

输出如下:

$make               

Usage:
 make [target]

Targets:
init                   初始化项目工具和环境
config                 生成配置文件和枚举
api                    由 proto 生成接口层代码
generate               generate
gen                    generate 缩写
fmt                    fmt 格式化代码
lint                   lint 代码检查
build                  build 编译
all                    重新生产代码并编译
run                    run 本地编译 运行
sonar                  sonar
clean                  clean
help                   show help

Read more

代码 Refactoring

重构不必谈之色变。 它也不是洪水猛兽,而是开发过程中持续进行的优化过程。让我们开始学习这个主题,重新认识它的价值。 🌟整洁代码 重构的主要目的是消除技术债务。它将混乱变成整洁的代码和简单的设计。 * 对于其他程序员来说,整洁的代码是显而易见的。 我并不是在谈论超级复杂的算法。糟糕的变量命名、臃肿的类和方法、魔法数字 - 等等,所有这些都会让代码变得混乱和难以理解。 * 整洁的代码不包含重复。 每次你需要对重复的代码进行更改时,你都必须记住对每个实例进行相同的更改。这会增加认知负担并减慢进度。 * 整洁的代码包含最少数量的类和其他活动部件。 代码越少,脑子里需要记住的东西就越少。代码越少,维护工作就越少。代码越少,错误就越少。代码就是责任,保持代码简短。 * 整洁的代码通过所有测试。 如果只有 95% 的测试通过,你就知道代码不整洁。如果测试覆盖率为 0%,你就知道你完蛋了。 * 整洁的代码维护成本低! 🗑️技术债(What) 每个人都尽最大努力从头开始编写出色的代码。可能没有程序员会故意编写不干净的代码,从而损害项目。但是干净的代码在什么时

By brian

CSV 格式说明和应用

问题 我们常常将多个字符串item使用逗号拼接成一个字符串,用来表示数组,使用时再用逗号切割成为数组。比如安卓机型列表: ALN-AL10,ALN-AL10,BRA-AL00,ALN-AL00/ALN-AL80 直到有一天,苹果设备也要用到这个机型列表,而它的每个机型都带着逗号,那我们使用逗号切割就得到了错误的数据。 iPhone15: iPhone15,4 iPhone15Plus: iPhone15,5 iPhone15Pro: iPhone16,1 iPhone15Pro_Max: iPhone16,2 为了解决这个问题,首先想到了换一个分隔符,比如 | ,再比如用一些不可见字符 : 0x01。 但我们不能保证这些字符串 item 一定不包含这些特殊字符,也许还有更好的方法。 既然是逗号分隔,首先想到的就是 CSV格式,毕竟 CSV 的全称就是Comma-Separated Values逗号分隔值。它是如何解决这个问题的? CSV格式 CSV 的RFC说明文档:https://datatracker.ietf.

By brian
开启了http2,但是http2_max_field_size 还在用默认值吗?

开启了http2,但是http2_max_field_size 还在用默认值吗?

排查1个异常接口,学到一个降本和接口提速的新思路。另外找到1个charles的"bug" 现象 测试同学反馈在iOS13设备上请求接口报错,将请求复制为 curl 命令。分别导入 apifox 和 在终端执行: * 在 apifox 请求正常 ✅ * 在终端请求失败 ❌ curl: (56) Failure when receiving data from the peer 测试同学又反馈另一个手机支持请求接口返回正常。 定位 有了正常和错误的请求curl,那直接对比二者差异就很简单了。对比发现,在终端执行失败的请求中多了一个较大的Cookie: app_token。按历史经验基本能确定是因为 Cookie 这个 header 条目太大,超过服务器的限制。 找云平台确定相关配置: ELB http1: header头限制 128KB,body 限制一个10G http2:

By brian
沪ICP备2022013452号-1