专栏名称: HULK一线技术杂谈
HULK是360的私有云平台,丰富的一线实战经验,为你带来最有料的技术分享
目录
相关文章推荐
数据宝  ·  数据复盘 | ... ·  3 天前  
第一财经  ·  登陆工信部公告!小米,传来大消息→ ·  6 天前  
经济参考报  ·  上涨0.2%!重要数据出炉→ ·  6 天前  
51好读  ›  专栏  ›  HULK一线技术杂谈

Golang:无惧makefile

HULK一线技术杂谈  · 公众号  ·  · 2017-09-26 18:01

正文

女主宣言

目前发现项目中的好多小伙伴在编写go程序的时候,基本都是使用命令行来执行“go build”、“go test”这些命令。但是发现很是麻烦而且效率不高,所以今天小编将本文带给大家,希望能够帮助大家提高效率。

PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!


在平时的开发过程中,总是习惯于手动的去反复执行“go build”、“go test”这些命令。如果没有参数的话,感觉还好。但是如果在复杂的任务中,这将会变的非常的痛苦。而且这并不是一个好的习惯。对于这个问题,你可能会有一些其他的方式来解决,比如可以写一个shell脚本来执行。但是对于我来讲,写一个makefile才是一个更好的选择。在makefile里面,我们可以把所有的任务都整合在一起。在本篇文章中,我会将makefile整合到我的项目中。


# Go parameters

GOCMD=go

GOBUILD=$(GOCMD) build

GOCLEAN=$(GOCMD) clean

GOTEST=$(GOCMD) test

GOGET=$(GOCMD) get

BINARY_NAME=mybinary

BINARY_UNIX=$(BINARY_NAME)_unix


all: test build

build:

       $(GOBUILD) -o $(BINARY_NAME) -v

test:

       $(GOTEST) -v ./...

clean:        $(GOCLEAN)        rm -f $(BINARY_NAME)        rm -f $(BINARY_UNIX)

run:        $(GOBUILD) -o $(BINARY_NAME) -v ./...        ./$(BINARY_NAME)

deps:        $(GOGET) github.com/markbates/goth

       $(GOGET) github.com/markbates/pop


# Cross compilation

build-linux:        CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_UNIX) -v

docker-build:        docker run --rm -it -v "$(GOPATH)":/go -w /go/src/bitbucket.org/rsohlich/makepost golang:latest go build -o "$(BINARY_UNIX)" -v


假设我喜欢保持ERY规则的概念。因此,在文件的顶部声明常用的命令和变量是很方便的。并在文件中进一步引用它们。


# Basic go commands

GOCMD=go

GOBUILD=$(GOCMD) build

GOCLEAN=$(GOCMD) clean

GOTEST=$(GOCMD) test

GOGET=$(GOCMD) get


# Binary names

BINARY_NAME=mybinary

BINARY_UNIX=$(BINARY_NAME)_unix


makefile目标被定义为标签 “:” 之后。如果给出的参数是给定的,则由make工具执行。如果没有指定参数,则默认执行第一个任务。在本例中将执行“all”任务。


> make run // call specific task

> make // make tool calls "all" task


1

基础命令

makefile的一个重要部分是构建步骤。使用变量$(GOBUILD)执行“go build”命令。程序名是由“-o $(BINARY_NAME)”定义的,而且使用“-v”切换到详细模式也很有用。使用详细模式,可以看到当前构建的包。


build:

       $(GOBUILD) -o $(BINARY_NAME) -v // expands to: "go build -o mybinary -v"


因为我们可以比较懒,所以目标在“run”这儿。目标构建生成程序并且接着运行它。


run:        $(GOBUILD) -o $(BINARY_NAME) -v ./...        ./$(BINARY_NAME)


当然,测试命令也应该是项目makefile的一部分。我个人更倾向于选择详细模式,以便能够调试并更好地观察测试运行。


test:

       $(GOTEST) -v ./...


如果项目使用的是CI/CD,或者只是为了一致性,最好保留包中使用的依赖项列表。这是由“deps”任务完成的,该任务应该通过“go get”命令获得所有必要的依赖项。


deps:        $(GOGET) github.com/markbates/goth        $(GOGET) github.com/markbates/pop


为了将这部分有用的命令封装起来,clean命令会被包含到makefile中。

在$(BINARY_XXX)变量中添加了“rm -f”命令以删除带有自定义名称的二进制文件。通常,另一个清理命令可能是这个部分的一部分。


clean:        $(GOCLEAN)        rm -f $(BINARY_NAME)        rm -f $(BINARY_UNIX)


2

跨编译器命令

如果项目的目的是在另一个平台上运行,而不是在开发的平台上运行,那么可以使用交叉编译命令来创建文件。我通常在容器中运行Linux平台上的二进制文件,因此makefile包含了Linux构建。


build-linux:        CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_UNIX) -v


如果你的代码使用C绑定,你可能会遇到一些问题。CGO的问题在于,你需要一个兼容给定平台的gcc。因此,如果在osx/windows上进行开发,你需要构建gcc来为Linux编译。至少对我来说,在OSX上编译C代码并不是那么简单的。如果需要CGO,那么docker映像是创建Linux构建的最佳方式。唯一的要求是:必须安装Docker。


docker-build:        docker run --rm -it -v "$(GOPATH)":/go -w /go/src/bitbucket.org/rsohlich/makepost golang:latest go build -o "$(BINARY_UNIX)" -v

总结

通过这种方式,可以使你的开发过程更加有效和流畅。如果有什么疑问,不要犹豫发表评论或提问,我们很乐意回答或探讨。Enjoy!

扫描下方
二维码
了解更多内容