01 

介绍

Go 提供一个名为go的命令,该命令可自动下载、构建、安装和测试 Go 包和命令。

Go 提供go命令,官方的目的是为了不需要编写 Makefile,而是能够仅使用 Go 源代码本身中的信息来构建 Go 代码。

但是,我们在 Go 项目中也不需要完全摒弃使用 make 和 Makefile,可以使用 Makefile 的“伪目标”,简化使用 go 命令的复杂性,规范团队使用 go 命令的方式,提升个人或团队的生产力。

02 

make 和 Makefile

make 命令行工具可以自动判断是否需要重新编译程序,实际上 make 不仅限于程序,我们可以使用它来描述任何任务,只要其他文件发生更改,某些文件就必须从其他文件自动更新。

在使用 make 命令行工具之前,我们需要编写一个名为 Makefile 的文件,该文件描述程序中文件之前的关系,并提供用于更新每个文件的命令。也就是说 Makefile 决定 make 做什么。

关于 Makefile 的介绍,感兴趣的读者朋友,可以查阅相关资料深入学习,本文仅介绍 Makefile 的规则(格式),如下所示:

target ... : prerequisites ...
<Tab>command
    ...
    ...

target ... : prerequisites ...;command

阅读上面示例代码,target 是目标文件,多个目标文件之间使用空格分隔,一般只有一个目标文件,也可以是“伪目标”(某个操作的名字);prerequisites 是先决条件;command 是“命令”,可以在 prerequisites 后面,使用分号分隔,也可以另起一行,但是必须以<Tab>开头,如果想要使用其他键,可以使用内置变量 .RECIPEPREFIX 声明。

target 目标是必须的,不可省略。prerequisites 和 command 是可选的,但是二者必须存在其一。

03 

Go 项目使用 Makefile

在 Go 项目中使用 Makefile,一般我们只会使用“伪目标”,我们使用 go build 构建可执行文件为例,介绍 Go 项目怎么使用 Makefile。

示例代码:

build:
  go build -o blog

阅读上面示例代码,我们编写一个简单的 Makefile,定义一个“伪目标” build,命令是 go build -o blog,构建名为 blog 的可执行文件。

使用 make 命令行工具,运行“伪目标”build。

make build

运行 make build,终端打印出 Makefile 中“伪目标” build 的命令。

go build -o blog

如果我们不想打印出执行的命令,可以在命令前面加上 @ 符号。

在实际项目开发时,我们可能需要构建多个操作系统的可执行文件,我们再编写一个 Makefile,新增三个“伪目标”,分别是windows、linux 和 darwin。

示例代码:

APP=blog

build:
        @go build -o ${APP}
windows:
        @GOOS=windows go build -o ${APP}-windows
linux:
        @GOOS=linux go build -o ${APP}-linux
darwin:
        @GOOS=darwin go build -o ${APP}-darwin

阅读上面示例代码,我们定义一个自定义变量 APP,在命令行中使用 $(APP) 调用变量,并且 GOOS 指定操作系统,使用@开头,不再打印执行命令。

运行 make windowsmake linux 和 make darwin,分别构建 windows、linux 和 drawin 操作系统的可执行文件。

运行结果如下:

.
├── Makefile
├── blog
├── blog-darwin
├── blog-linux
├── blog-windows
├── go.mod
└── main.go

需要注意的是,如果有文件名和“伪目标”同名,那么该“伪目标”无法使用 make 命令执行指定的 command。因为 make 发现与“伪目标”同名的文件已存在,将不会再重新构建,所以就不会运行指定的 command,为了避免出现该问题,可以使用内置目标名.PHONY声明这些“伪目标”名是“伪目标”,而不是与“伪目标”同名的文件。

完整 Makefile 文件:

APP=blog

.PHONY: help all build windows linux darwin

help:
        @echo "usage: make <option>"
        @echo "options and effects:"
        @echo "    help   : Show help"
        @echo "    all    : Build multiple binary of this project"
        @echo "    build  : Build the binary of this project for current platform"
        @echo "    windows: Build the windows binary of this project"
        @echo "    linux  : Build the linux binary of this project"
        @echo "    darwin : Build the darwin binary of this project"
all:build windows linux darwin
build:
        @go build -o ${APP}
windows:
        @GOOS=windows go build -o ${APP}-windows
linux:
        @GOOS=linux go build -o ${APP}-linux
darwin:
        @GOOS=darwin go build -o ${APP}-darwin

阅读上面示例代码,我们可以看到 Makefile 中第二个“伪目标” all,该目标只有 4 个先决条件,没有任何命令。执行 make all 命令,可以批量执行多个“伪目标”。该命令等同于以下命令:

make build
make windows
make linux
make darwin

细心的读者朋友们阅读到此处,心中可能会有一个疑问,想要知道 Makefile 中包含哪些“目标”,必须查看 Makefile 文件吗?

不必如此,我们可以在 Makefile 中编写一个“伪目标” help,用于描述 Makefile 中的“伪目标”列表和使用示例等。

Make 命令运行时,如果不指定“目标”,默认执行 Makefile 文件的第一个“目标”。一般将 help 作为 Makefile 的第一个“伪目标”,我们可以执行 make 或 make help 命令,输出使用方法。

golang项目:

对于go项目, 一般会使用go的命令执行:测试, 编译,运行,语法检查等命令

一个完善的 Go 项目经常会执行哪些命令?

  • go vet 静态检查
  • go test 运行单元测试
  • go fmt 格式化
  • go build 编译
  • go run 运行 ...

所以一个适用于 Go 项目的 Makefile 也应该支持这些命令。

  • make default : 编译
  • make fmt: 格式化
  • make vet: 静态检查
  • make test: 运行测试
  • make install: 下载依赖库
  • make clean: 移除编译的二进制文件

示例:

BINARY="example"
VERSION=1.0.0
BUILD=`date +%FT%T%z` PACKAGES=`go list ./... | grep -v /vendor/`
VETPACKAGES=`go list ./... | grep -v /vendor/ | grep -v /examples/`
GOFILES=`find . -name "*.go" -type f -not -path "./vendor/*"` default:
@go build -o ${BINARY} -tags=jsoniter list:
@echo ${PACKAGES}
@echo ${VETPACKAGES}
@echo ${GOFILES} fmt:
@gofmt -s -w ${GOFILES} fmt-check:
@diff=?(gofmt -s -d $(GOFILES)); \
if [ -n "$$diff" ]; then \
echo "Please run 'make fmt' and commit the result:"; \
echo "$${diff}"; \
exit 1; \
fi; install:
@govendor sync -v test:
@go test -cpu=1,2,4 -v -tags integration ./... vet:
@go vet $(VETPACKAGES) docker:
@docker build -t wuxiaoxiaoshen/example:latest . clean:
@if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi .PHONY: default fmt fmt-check install test vet docker clean

windows下安装make

# 安装choco使用该软件工具进行make安装

# 1.管理员身份打开powershell,执行命令
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) # 2.安装make
choco install make 安装完成后, 例如路径: C:\ProgramData\chocolatey\bin\make.exe
需要将该路径在goland中添加 Build Tools > Make中进行配置

注意点:

1.文件的命令行前面必须是tab, 否则会出现各种奇奇怪怪的报错,建议下载插件进行文件校验

Makefile执行过程中出错:make: *** No rule to make target ` ‘, needed by xxx. Stop.

2.在windows系统下进行交叉编译的时候,跟linux下设置环境变量有些不同

set GOOS=windows; set GOARCH=amd64; go build  -v -ldflags "-w -s" -o golang-demo_windows.exe ./cmd/app/main.go
#说明
使用set进行设置
使用分号设置多个

参考:

golang项目之Makefile的更多相关文章

  1. Golang项目目录结构组织

    其实golang的工程管理还是挺简单的,完全使用目录结构还有package名来推导工程结构和构建顺序. 当然,首先要说的是环境变量$GOPATH,项目构建全靠它.这么说吧,想要构建一个项目,就要将这个 ...

  2. golang项目中使用条件编译

    golang项目中使用条件编译 C语言中的条件编译 golang中没有类似C语言中条件编译的写法,比如在C代码中可以使用如下语法做一些条件编译,结合宏定义来使用可以实现诸如按需编译release和de ...

  3. Emacs中多个golang项目的配置方法

    概述 最近使用golang开发项目时, 发现有时需要同时进行多个golang项目. 在这种情况下, 如果把所有的项目都放在 GOPATH 之下, 不仅管理麻烦(因为各个项目需要提交到不同的代码库), ...

  4. 关于go get安装git golang项目时报错的处理办法

    关于go get安装git golang项目时报错的处理办法 使用go get安装github上的项目时一般来说,不可避免会出错.各种错误的处理办法: 必须条件: 1.安装git并配置环境变量.下载地 ...

  5. Golang项目的测试实践

    Golang项目的测试实践 最近有一个项目,链路涉及了4个服务.最核心的是一个配时服务.要如何对这个项目进行测试,保证输出质量,是最近思考和实践的重点.这篇就说下最近这个实践的过程总结. 测试金字塔 ...

  6. 为Go项目编写Makefile

    为Go项目编写Makefile 借助Makefile我们在编译过程中不再需要每次手动输入编译的命令和编译的参数,可以极大简化项目编译过程. make介绍 make是一个构建自动化工具,会在当前目录下寻 ...

  7. Golang项目的配置管理——Viper简易入门配置

    Golang项目的配置管理--Viper简易入门配置 What is Viper? From:https://github.com/spf13/viper Viper is a complete co ...

  8. LibOpenCM3(二) 项目模板 Makefile分析

    目录 LibOpenCM3(一) Linux下命令行开发环境配置 LibOpenCM3(二) 项目模板 Makefile分析 LibOpenCM3 项目模板 项目模板地址: https://githu ...

  9. 使用 SmartIDE 开发golang项目

    目录 概述 架构 开发视图 快速开始 安装 SmartIDE CLI 环境 启动 创建环境 安装工具 调试 基本调试 Start 命令调试 很荣幸在去年加入到 SmartIDE 产品组,从事开发工作, ...

  10. golang 项目实战简明指南

    原文地址 开发环境搭建 golang 的开发环境搭建比较简单,由于是编译型语言,写好 golang 源码后,只需要执行 go build 就能将源码编译成对应平台(本文中默认为 linux)上的可执行 ...

随机推荐

  1. vue动态绑定样式

    每次点击方块时通过三元表达式,改变对应的class,每一个不同的class对应不同的样式,从而通过改变class实现样式的切换. 实现代码 <template> <div class ...

  2. Dash 2.18版本新特性介绍

    本文示例代码已上传至我的Github仓库:https://github.com/CNFeffery/dash-master Gitee同步仓库地址:https://gitee.com/cnfeffer ...

  3. 模N取余法实现大整数进制转换 ——C语言版(2-16进制均可)

    思路如标题所说采用模N取余法,难点是这个除法过程如何实现. 个人推荐先到这篇博客学习一下,大佬的思路就是不一样:大数除法--超详细讲解 我所做的就是在上面博文代码的基础上增加了循环,用一个字符数组逆序 ...

  4. 有哪些让你「 爽到爆炸 」的 Windows 软件?

    前言 本文源于知乎的一个提问,如标题所示:有哪些让你「 爽到爆炸 」的 Windows 软件?今天大姚给大家分享6款C#/.NET开源且免费的Windows软件,希望可以帮助大家提高学习.开发.办公效 ...

  5. 深入理解Argo CD工作原理

    1. ArgoCD 的架构 ArgoCD 是一个 Kubernetes 原生的持续交付工具,它通过监控 Git 仓库中的应用定义来自动部署应用到 Kubernetes 集群.其核心架构由以下几个关键组 ...

  6. el-table

    el-table-column 渲染的顺序不对,第一列被渲染到最后 el-table-column 必须作为 el-table 或 el-table-column 的直接子元素使用,如果不是将会导致标 ...

  7. Flutter 不容错过的 7 大亮点 | Google I/O 精彩回顾

    Flutter 在今年的 Google I/O 上发布了许多重磅更新,欢迎大家和我们一起了解其中不容错过的 7 大亮点, 点击这里 观看 Flutter 不容错过的 7 大亮点 视频了解更多信息. F ...

  8. 深入理解 Nuxt.js 中的 app:created 钩子

    title: 深入理解 Nuxt 中的 app created 钩子 date: 2024/9/26 updated: 2024/9/26 author: cmdragon excerpt: 摘要:本 ...

  9. Linux_权限理解(详细PLUS)

    1.用户 Linux下有两种用户:超级用户(root)和普通用户: 超级用户:可以再linux系统下做任何事情,不受限制 普通用户:在linux下做有限的事情 超级用户的命令提示符是"#&q ...

  10. Kulla-Conty BRDF

    question: brdf中的几何因子考虑了微表面的自遮挡,当表面粗糙度较大或者与法线夹角越大时,这个因子越小,导致颜色越暗.这部分能量相等于直接忽略掉了,实际上被遮挡的光线会被反射,然后经过若干次 ...