使用 Makefile 构建指令集

简介: 使用 Makefile 构建指令集

使用 Makefile 构建指令集

make 是一个历史悠久的构建工具,通过配置 Makefile 文件就可以很方便的使用你自己自定义的各种指令集,且与具体的编程语言无关。例如配置如下的 Makefile :

run dev:
    NODE_ENV=development nodemon server.js

这样当你在命令行执行 make run dev 时其实就会执行 NODE_ENV=development nodemon server.js 指令。

使用 Makefile 构建指令集可以很大的提升工作效率。

Makefile 基本语法

<target>: <prerequisites>
    <commands>

target 其实就是执行的目标, prerequisites 是执行这条指令的前置条件, commands 就是具体的指令内容。

示例:

build: clean
    go build -o myapp main.go
clean:
    rm -rf myapp

这里的 build 有一个前置条件 clean ,意思就是当你执行 make build 时,会先执行 clean 的指令内容 rm-rf myapp ,然后再执行 build 的内容 go build-o myapp main.go

变量

自定义变量,示例:

APP=myapp
build: clean
    go build -o ${APP} main.go
clean:
    rm -rf ${APP}

PHONY

上例中的定义了 target 目标有 buildclean ,如果当前目录中正好有一个文件叫做 buildclean,那么其指令内容不会执行,这是因为 make 会把 target 视为文件,只有当文件不存在或发生改变时才会去执行命令。

为了解决这个问题,我们需要使用 PHONY 声明 target 其实是伪目标:

APP=myapp
.PHONY: build
build: clean
    go build -o ${APP} main.go
.PHONY: clean
clean:
    rm -rf ${APP}

多个 PHONY 也可以统一声明在一行中:

.PHONY: build clean

递归的目标

假设我们的工程目录结构如下:

~/project
├── main.go
├── Makefile
└── mymodule/
      ├── main.go
      └── Makefile

文件根目录下还有一个文件夹 mymodule,它可能是一个单独的模块,也需要打包构建,并且定义有自己的 Makefile :

# ~/project/mymodule/Makefile
APP=module
build:
    go build -o ${APP} main.go

现在当你处于项目的根目录时,如何去执行 mymodule 子目录下定义的 Makefile 呢?

使用 cd 命令也可以,不过我们有其它的方式去解决这个问题:使用 -C 标志和特定的 ${MAKE} 变量。

修改项目根目录中的 Makefile 为:

APP=myapp
.PHONY: build
build: clean
    go build -o ${APP} main.go
.PHONY: clean
clean:
    rm -rf ${APP}
.PHONY: build-mymodule
build-mymodule:
    ${MAKE} -C mymodule build

这样,当你执行 make build-mymodule 时,其将会自动切换到 mymodule 目录,并且执行 mymodule 目录下的 Makefile 中定义的 build 指令。

shell 输出作为变量

我们可以把 shell 中执行的指令的输出作为变量:

V=$(shell go version)
gv:
    echo ${V}

这里执行 make gv 就会先执行 go version 指令然后把输出的内容赋值给变量 V 。

判断语句

假设我们的指令依赖于环境变量 ENV ,我们可以使用一个前置条件去检查是否忘了输入 ENV

.PHONY: run
run: check-env
    echo ${ENV}
check-env:
ifndef ENV
    $(error ENV not set, allowed values - `staging` or `production`)
endif

这里当我们执行 make run 时,因为有前置条件 check-env 会先执行前置条件中的内容,指令内容是一个判断语句,判断 ENV 是否未定义,如果未定义,则会抛出一个错误,错误提示就是 error 后面的内容。

帮助提示

添加 help 帮助提示:

.PHONY: build
## build: build the application
build: clean
    @echo "Building..."
    @go build -o ${APP} main.go
.PHONY: run
## run: runs go run main.go
run:
    go run -race main.go
.PHONY: clean
## clean: cleans the binary
clean:
    @echo "Cleaning"
    @rm -rf ${APP}
.PHONY: setup
## setup: setup go modules
setup:
    @go mod init \
        && go mod tidy \
        && go mod vendor
.PHONY: help
## help: prints this help message
help:
    @echo "Usage: \n"
    @sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' |  sed -e 's/^/ /'

这样当你执行 make help 时,就是打印如下的提示内容:

Usage:
  build   build the application
  run     runs go run main.go
  clean   cleans the binary
  setup   setup go modules
  help    prints this help message
目录
相关文章
|
Shell
【开发小技巧】添加鼠标右键通过xx打开文件夹菜单
【开发小技巧】添加鼠标右键通过xx打开文件夹菜单
569 0
【开发小技巧】添加鼠标右键通过xx打开文件夹菜单
|
3天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
271 116
|
18天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
12天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
663 219
|
5天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
349 34
Meta SAM3开源:让图像分割,听懂你的话
|
10天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1573 157
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
897 61