Makefile是组织编译的命令脚本文件-构建生成可执行文件的依赖关系树.
make
根据makefile的规则关系树, 构建出编译可执行程序.
1
2
3
4
|
# 目标: 目标依赖
# 命令
a.out: demo.c
gcc -o $@ $<
|
make指令
windows 环境
运行make -v
会出现:
1
2
|
'make' 不是内部命或外部命令, 也不是可余小宁的程序, 或批处理文件.
# 系统在环境变量中找不到 make 命令执行文件
|
解决方法:
- 找到
mingw
安装目录, 打开bin
目录, 找到mingw32-make.exe
- 将
mingw32-make.exe
将该文件重命名为make.exe
编译过程
编译过程图
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
.PHONY: clean
CC=g++
BIN=exec
OBJS=AddTwoSum.o utils.o
$(BIN): $(OBJS)
@echo "start compiling..."
@echo $(CC)
$(CC) -o $(BIN) $(OBJS)
@echo "compile done"
AddTwoSum.o: AddTwoSum.cpp
$(CC) -c -o $@ $<
utils.o: utils.cpp
$(CC) -c -o $@ $<
clean:
rm -f $(BIN) $(OBJS)
|
1
2
3
4
5
6
7
8
9
|
#条件赋值 ?=
#追加赋值 +=
CC = g++
CC ?= gcc
OBJS = AddTwoSum.o
OBJS += utils.o
echo:
@echo $(CC)
@echo $(OBJS)
|
1
2
3
4
5
6
7
8
9
10
11
|
# 使用 := 赋值, 立即变量
# 使用 = 赋值, 延迟变量(关系变量)
a = 1
b = 2
val_a := $(a) # val_a=1 解析即赋值 立即解析赋值
val_b = $(b) # val_b的值随着b的变化而变化 绑定变量关系
a = 10
# b = 20
echo:
@echo $(val_a)
@echo $(val_b)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# 常用自动变量
# $@ 目标
# $^ 所有依赖项
# $< 目标依赖项中的第一个
# $? 所有依赖项中被修改过的
.PHONY: clean
CC=g++
BIN=exec
OBJS=AddTwoSum.o utils.o
$(BIN): $(OBJS)
@echo "start compiling..."
@echo $(CC)
$(CC) -o $@ $^
@echo "compile done"
AddTwoSum.o: AddTwoSum.cpp
$(CC) -c -o $@ $<
utils.o: utils.cpp
$(CC) -c -o $@ $<
clean:
rm -f $(BIN) $(OBJS)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
.PHONY: echo
SRC = demo.c demo1.c
OBJ = $(SRC:.c=.o)
OBJ1 = $(SRC:%.c=%.o)
echo:
@echo "SRC=$(SRC)"
@echo "OBJ=$(OBJ)"
@echo "OBJ1=$(OBJ1)"
# SRC=demo.c demo1.c
# OBJ=demo.o demo1.o
# OBJ1=demo.o demo1.o
|
环境变量运行时载入makefile. 如果有相同命名的变量, 系统环境变量会被覆盖.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.PHONY: echo
CFLAGS = -g
echo:
@echo "CFLAGS = $(CFLAGS)"
@echo "SHELL = $(SHELL)"
@echo "MAKE = $(MAKE)"
@echo "HOSTNAME = $(HOSTNAME)"
# CFLAGS = -g
# SHELL = D:/sortwares/Git/usr/bin/sh.exe
# MAKE = D:/sortwares/mingw64/bin/make
# HOSTNAME = TX-PC0N4UHP
# 运行make 可以传值改变 export方式
# make HOSTNAME=CodeMax
# HOSTNAME = CodeMax
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# ifeq 判断相等
mode = debug
echo:
ifeq ($(mode),debug)
@echo "debug mode"
else
@echo "release mode"
endif
# ifneq
echo:
ifeq ($(mode),)
@echo "debug mode"
else
@echo "release mode"
endif
# ifdef
echo:
ifdef mode
@echo "debug mode"
else
@echo "release mode"
endif
|
- 自定义函数 通过call调用
- make内嵌函数 直接make调用
- 函数与参数使用空格隔开 参数之间使用,隔开
1
2
3
4
5
|
# 内嵌函数
SRC = $(wildcard *.cpp)
echo:
@echo "SRC = $(SRC)"
|
1
2
3
4
5
6
7
8
|
# 自定义函数
define func
@echo "param1 = $(0)"
@echo "param = $(1)"
endef
echo:
$(call func, hello world)
|
1
|
$(foreach VAR, LIST, TEXT)
|
- VAR 将空格隔开的每一个选项赋值给VAR
- TEXT 处理VAR的脚本
1
2
3
4
5
6
|
# $(if(condition, then[, else]))
install__path =
install_path = $(if $(install__path), $(install__path), /usr/local)
echo:
@echo "$(install_path)"
|
1
|
# $(call def_func, <parm1>, <param2>...)
|
1
2
|
# $(error TEXT...)
# $(warning TEXT...)
|
example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
# 如果当前目录中,正好有一个文件叫做clean,那么这个命令不会执行。
# 因为Make发现clean文件已经存在,就认为没有必要重新构建了,就不会执行指定的rm命令
# 就有了下面的伪声明
.PHONY: clean
# 编译Cpp
CC = g++
# 设置编译参数设置
# -g表示编译时候加入调试信息,
# -DDEBUG表示编译debug版本
# -W -Wall表示输出所有警告
# -fPIC是生成dll时候用的
CFLAGS = -g -DDEBUG -W -Wall -fPIC
# 头文件的目录为./ 当前目录
HEADER = -I./
ALGONAME = AddTwoSum
TOOLNAME = utils
OBJS= $(ALGONAME).o $(TOOLNAME).o
TARGET = algo
$(TARGET): $(OBJS)
@echo "start compiling..."
$(CC) $(CFLAGS) -o $@ $^
@echo "compile done"
$(ALGONAME).o: $(ALGONAME).cpp
$(CC) -c -o $@ $<
$(TOOLNAME).o: $(TOOLNAME).cpp
$(CC) -c -o $@ $<
clean:
rm -f $(TARGET) $(OBJS)
|
参考