0%

Makefile学习

Makefile规则

1
2
3
4
5
6
7
8
target:prerequisites 	#目标:依赖的文件或者其他目标
cmd_1
cmd_2
cmd_3

.PHONY:clean #伪目标
clean:
cmd

Makefile变量、模式匹配

变量

  • 系统变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .PHONY: all
    all:
    echo "$(CC)"
    echo "$(AS)"
    echo "$(MAKE)"
    #输出结果
    #echo "cc"
    #cc
    #echo "as"
    #as
    #echo "make"
    #make
  • 自定义变量

    • =,延迟赋值(引用此变量的时候才赋值)

      1
      2
      3
      4
      5
      6
      7
      8
      A=123
      B=$(A)
      A=456
      .PHONY: all
      all:
      echo "$(B)"
      #输出结果
      #456
  • :=,立即赋值

    1
    2
    3
    4
    5
    6
    7
    8
    A=123
    B:=$(A)
    A=456
    .PHONY: all
    all:
    echo "$(B)"
    #输出结果
    #123
  • ?=,空赋值(变量为空的时候才有效)

    1
    2
    3
    4
    5
    6
    7
    8
    A?=123
    #B:=$(A)
    A?=456
    .PHONY: all
    all:
    echo "$(A)"
    #输出结果
    #123
  • +=,追加赋值(不会改变变量的值)

    1
    2
    3
    4
    5
    6
    7
    8
    A?=123
    #B:=$(A)
    A+=456
    .PHONY: all
    all:
    echo "$(A)"
    #输出结果
    #123 456
  • 自动化变量

    • $<,第一个依赖文件

    • $^,全部的依赖文件

    • $@,目标

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      all:targeta targetb
      echo "$<"
      echo "$^"
      echo "$@"

      targeta:

      targetb:

      #输出结果
      #echo "targeta"
      #targeta
      #echo "targeta targetb"
      #targeta targetb
      #echo "all"
      #all

模式匹配

%,匹配任意多个非空字符

类似于shell的*通配符

1
2
%:
echo "$@"

默认规则

.o文件默认使用.c文件编译

Makefile条件分支

1
2
3
4
5
ifeq(var1,var2)
....
else
....
endif
1
2
3
4
5
ifneq(var1,var2)
....
else
....
endif

Makefile常用函数

patsubst

模式替换函数

1
2
3
.PHONY:all
all:
echo "$(patsubst %.c,%.o,x.c.c bar.c)"

把字串“x.c.c bar.c”中以.c 结尾的单词替换成以.o 结尾的字符。函数的返回结果 是“x.c.o bar.o”

notdir

取文件名函数

1
2
3
.PHONY:all
all:
echo "$(notdir src/foo.c hacks)"

返回值为:“foo.c hacks”

wildcard

获取匹配模式文件名函数

1
2
3
.PHONY:all
all:
echo "$(wildcard *.c)"

返回值为当前目录下所有.c 源文件列表

foreach

函数“foreach”不同于其它函数。它是一个循环函数。类似于 Linux 的 shell 中的 for 语句

1
2
3
4
5
6
7
dirs := a b c d 
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

.PHONY:all
all:
echo "$(files)"

把文件夹里边的文件全部找出来

Makefile解决头文件依赖

  1. 写一个头文件,并把头文件添加到编译器的头文件的路径
  2. 实时检查头文件的更新情况,一旦头文件发生变化,应该重新编译所有相关文件

较为完善的Makefile

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
33
ARCH?=x86
ifeq ($(ARCH),x86)
CC=gcc
else
CC=arm-linux-gnueabihf-gcc
endif

TARGET=mp3
BUILD_DIR=build
SRC_DIR=module1 module2
INC_DIR=include
CFLAGS=$(patsubst %,-I%,$(INC_DIR))

INCLUDE= $(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h))
SOURCES= $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCES)))
VPATH=$(SRC_DIR)


$(BUILD_DIR)/$(TARGET):$(OBJS)
$(CC) $^ -o $@ $(CFLAGS)

$(BUILD_DIR)/%.o:%.c $(INCLUDE) | create_build
$(CC) -c $< -o $@

.PHONY:create_build
create_build:
mkdir -p $(BUILD_DIR)

.PHONY:clean
clean:
rm -rf $(BUILD_DIR)

-------------THE END-------------

欢迎关注我的其它发布渠道