前言 📚
请问你是如何打包Go语言开发的项目呢?
是直接命令行输入?
go build .
开发调试时?
go run main.go
但是我们看到开源的Go语言项目运行时是:
make build || make install
我们打包运行的这个过程,有一个更加贴切的词语叫做构建项目。
本文将个大家介绍 Makefile这个广为使用的构建工具,它是开源的,不仅仅适用于Go语言中,C语言或者C++等项目也同样使用。
1、make 简介 🎯
在软件开发中,make 通常被视为一种软件构建工具。该工具主要经有读取一种名为 makefile 或者 Makefile的文件来实现软件的自动化构建。
它会通过一种被称之为 target概念的来检查相关文件之间的依赖关系,这种依赖关系的检查系统非常简单,主要通过对比文件的修改时间来实现。
在大多数情况下,我们主要用它来编译源代码,生成结果代码,然后把结果代码连接起来生成可执行文件或库文件。
2、安装 ⬇️
Mac 系统自带 make 命令,如果是 linux 就需要自己安装下 make,命令很简单。 Centons 系统安装 make命令:
yum install -y make
3、创建配置文件
新建一个工程,工程目录大概如下:
main.go 源码如下:
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
看着和以往的项目没区别,但是多个一个 Makefile 文件,如何使用 Makefile 构建项目呢,需要在里面添加如下代码:
BINARY_NAME=app
run:
go build -o bin/${BINARY_NAME} -v
./bin/${BINARY_NAME}
来解释一下各行的意思:
- 第一行: 声明了一个变量 BINARY_NAME,它的值是app,方便后面使用
- 第二行:声明了一个target,可以理解为一个对外的方法
- 第三行:这就是该 target被调用时执行的脚本,当时是build该项目,编译后的二进制文件放在当前工程根目录下的 bin目录下,名字是变量 BINARY_NAME的值
- 第四行:这一行是直接执行当前 bin目录下的二进制文件
注意
第三行和第四行前面要用 tab缩进,否则会报错
Makefile:3:*** missing separator. Stop.
附线上案例:
.PHONY: build
SERVICE := youservername
PACKAGE := test
MAIN := main
REGISTRY := zookeeper
AUTHOR := $(shell git log --pretty=format:"%an"|head -n 1)
VERSION := $(shell git rev-list HEAD | head -1)
BUILD_INFO := $(shell git log --pretty=format:"%s" | head -1)
BUILD_DATE := $(shell date +%Y-%m-%d\ %H:%M:%S)
CUR_PWD := $(shell pwd)
GO_VERSION := $(shell go version)
export GO111MODULE=on
export GOPROXY=***
LD_FLAGS='-X "$(PACKAGE)/version.TAG=$(TAG)" -X "$(PACKAGE)/version.VERSION=$(VERSION)" -X "$(PACKAGE)/version.AUTHOR=$(AUTHOR)" -X "$(PACKAGE)/version.BUILD_INFO=$(BUILD_INFO)" -X "$(PACKAGE)/version.BUILD_DATE=$(BUILD_DATE)" -X "$(PACKAGE)/version.GO_VERSION=$(GO_VERSION)"'
default: build
build:
go build -tags "$(REGISTRY)" -ldflags $(LD_FLAGS) -o ./bin/$(SERVICE) ./$(MAIN)
race:
go build -ldflags $(LD_FLAGS) -i -v -o ./bin/$(SERVICE) -race ./$(MAIN)
dev: build
cp $(CUR_PWD)/conf/conf_dev.ini $(CUR_PWD)/conf/conf.ini && ./bin/$(SERVICE) -v=true
clean:
rm bin/*
4、开始构建 🔛
make run