Makefile 文件说明

发布时间 2023-07-11 21:37:02作者: 2gbxzhdaz

https://github.com/jaywcjlove/reference/blob/main/docs/make.md

https://zhuanlan.zhihu.com/p/47390641

https://makefiletutorial.com/


target ... : prerequisites ...
    recipe
    ...
    ...

# -------------------------------------------------------------------------- 常用符号
#   target:             即自定义的要执行的命令
#   prerequisites:      先决条件(依赖),执行在 target 之前,多个用空格隔开
#   tab:                每个 command 前面都要有制表符(空格无效),用于标示这是命令
#   recipe:             具体执行的命令
#   .PHONY              伪指令,主要作用是避免与已存在的同名文件冲突,加上此参数后,当存在冲突文件时也会执行 target,否则会报错
#   ${val}              表示变量(像 SHELL 一样使用)
#   #                   表示注释

# 不带执行参数时默认执行第一个 Target ...

# -------------------------------------------------------------------------- 常用的预定义变量
# https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
# https://www.gnu.org/software/make/manual/html_node/Special-Variables.html

# $*   不包含扩展名的目标文件名称
# $+   所有的依赖,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
# $<   第一个依赖文件的名称
# $?   所有的依赖,以空格分开
# $@   Target 的完整名称
# $^   所有的依赖,以空格分开,不包含重复的依赖文件
# $%    如果目标是归档成员,则该变量表示目标的归档成员名称

# -------------------------------------------------------------------------- 

# 命令前加 @ 表示不显示当前命令,只显示执行结果

# 可以使用 \ 进行换行

Example


# 定义变量
PROJECT="main"
MAIN_PATH="main.go"
VERSION="v0.0.1"
DATE= `date +%FT%T%z`

# 可以执行函数,但函数不能存在 command
ifeq (${VERSION}, "v0.0.1") 
    VERSION=VERSION = "v0.0.1"
endif

version:
    @echo ${VERSION}

# .PHONY 有 build 文件,不影响 build 命令执行 ...
# 如果不使用 .PHONY 并且名为的文件与 Makefile 位于同一目录,则不会执行任何操作
# 这是因为 Make 将规则解释为"执行某某配方以创建名为XXX"的文件(由于文件已经存在,并且其依赖项未更改,因此不会执行任何操作)
# 但是若创建目标 .PHONY,它将告诉 make 工具该目标是虚构的,并且 make 不应期望它创建实际文件。因此它不会检查文件是否存在
# 这意味着: 如果文件确实存在,它的行为不会改变
.PHONY: build

build:
    @echo version: ${VERSION} date: ${DATE} os: Mac OS
    @go build -o ${PROJECT} ${MAIN_PATH}

install:
    @echo download package
    @go mod download

# 交叉编译运行在 Linux 系统环境
build-linux:
    @echo version: ${VERSION} date: ${DATE} os: linux-centOS
    @GOOS=linux go build -o ${PROJECT} ${MAIN_PATH}

run: build
    @./${PROJECT}

# 单独执行 => make clean
clean:
    rm -rf ./log

# -------------------------------------------------------------------------- 默认情况下执行第一个 Target

all: one two three

one:
	touch one
two:
	touch two
three:
	touch three

clean:
	rm -f one two three

Tips


# make 是 GNU make 的缩写,是控制源文件生成可执行文件的工具。在生成可执行文件的过程中,也会生成其他的中间文件,比如 .o 文件
# Makefile 是个文件,里面包含了编译和链接的规则,这些规则告诉 make 如何去做

# 当运行 make 命令时会在当前文件夹寻找 Makefile(Makefile也可以被命名为makefile和GNUmakefile)
# 然后根据 Makefile 的规则生成最终的目标