Using Makefile in the development of Golang

Source: Internet
Author: User
Tags docker run
This is a creation in Article, where the information may have evolved or changed.

I've been using Golang for a while, and during the development of Golang, I've been used to repeatedly manually execute go build and both go test commands. But now I'm out of this habit. If you only use simple commands without parameters, it may not be scary to do so directly. But in some complex tasks, if it's still manual execution go build go test , it can be a headache.

We can solve this problem by other means. For example, you can use a bash script to do this, or a better choice (at least for me) is to write a makefile. Make this tool is born to do these things, in makefile we can put all the common tasks together. I am not a makefile expert, so I may not be able to teach you how to write a good makefile. But in this article, I'm going to show you the Makefile I'm using, and most of my projects use these Makefile. Let's get Started:

# Go parametersGOCMD=goGOBUILD=$(GOCMD) buildGOCLEAN=$(GOCMD) cleanGOTEST=$(GOCMD) testGOGET=$(GOCMD) getBINARY_NAME=mybinaryBINARY_UNIX=$(BINARY_NAME)_unixall: test buildbuild:        $(GOBUILD) -o $(BINARY_NAME) -vtest:        $(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 compilationbuild-linux:        CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_UNIX) -vdocker-build:        docker run --rm -it -v "$(GOPATH)":/go -w /go/src/bitbucket.org/rsohlich/makepost golang:latest go build -o "$(BINARY_UNIX)" -v

I prefer the DPY (Don ' t Repeat yourself) principle. So, in makefile
The beginning of the definition defines commonly used commands and variables, and we can easily reference the defined commands and variables later.

# Basic go commandsGOCMD=goGOBUILD=$(GOCMD) buildGOCLEAN=$(GOCMD) cleanGOTEST=$(GOCMD) testGOGET=$(GOCMD) get# Binary namesBINARY_NAME=mybinaryBINARY_UNIX=$(BINARY_NAME)_unix

In : front of the goal called Makefile, for example build: , build is a goal. If you make specify a target when executing a command, for example make run , make builds the target. If no parameters are provided, make defaults to the first target. In our example, the called Target is all built.

$ make run ## call specific task$ make     ## make tool calls "all" task

Basic commands

The most critical part of makefile is building. When make executes, the defined variable is expanded, and $(GOBUILD) make go build actually executes the go build command. The generated binaries are named -o $(BINARY_NAME) . In addition, I find it -v useful to switch to verbose mode using parameters. In verbose mode, you can see the package that is currently being built.

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

Because most of us are lazy, we have a run goal called. The binaries run are built and executed after the build completes.

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

Generally speaking, the test command should be part of the makefile. I personally always like to use verbose mode to better debug and observe test run.

test:  $(GOTEST) -v ./...

If the project uses CI (continuous integration)/CD (continuous Delivery), even if it is just for consistency, it is a good practice to maintain a series of dependencies in the package. This can be deps done through the target, which go get gets all the dependent dependencies through the command.

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

cleanto end this section. rm -fThe order was used to remove the
$(BINARY_XXX)binary files.

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

Cross-compiling commands

If project development is on one system and needs to be run on another, it is convenient to include a cross-compiled command in makefile. I usually run binary on the container's Linux platform, so makefile contains the Linux build.

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

If your code uses C binding, you may encounter some problems. The problem with CGO is that you need a GCC that is compatible with a given platform. If the development is done on osx/windows, then you need to have a Linux-compatible GCC. At least for me, using the configuration gcc cross-compiling C code on OSX is not easy. If you need CGO, Docker mirroring is the best way to create a Linux build. The only requirement in this way is that Docker must be installed.

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

The Makefile example of this article can be found here.

Translator: The original use of the Makefile can actually be better, for example, in the comments below the original point, it should be indicated at least .PHONY: , build the other should be run the precondition. However, we can learn some of the desirable parts.

This article was translated from: Golang:don ' t afraid of makefiles

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.