makefile知识再整理(超详细)

前言

这个是我用xmind转markdown的效果,感觉很差,附上思维导图
思维导图我也上次至CSDN了:makefile知识再整理(超详细)

在这里插入图片描述

makefile

编译规则

目标文件

依赖文件

命令行

特性

1.只会执行更新过的程序文件的相关命令,如果都没更新过,make指令将不会执行(提高效率)

2.变量名代替文件名,一般是多个文件名,使用$进行替换

obj = a.o b.o
test : $(obj)
cc -o test $(obj)
a.o:a.c b.h
cc -c a.c
b.o:b.c
cc -c b.c

3.makefile命令尽量成首字母大写,即Makefile

#Makefile1
main:main.c add.c sub.c
gcc $^ -o $@

4.makefile中用#注释

#Makefile1
main:main.c add.c sub.c
gcc $^ -o $@

#Makefile2
main:main.o add.o sub.o
gcc $^ -o $@
main.o:main.c
gcc -c main.c
add.o:add.c
gcc -c add.c
sub.o:sub.c
gcc -c sub.c
.PHONY:clean
clean:
rm -f main.o add.o sub.o main

5.在命令前加@,在运行时,可以隐藏所执行命令

hello:hello.o
@gcc hello.o -o hello
hello.o:hello.c
@gcc -c hello

6.echo 命令相当于打印

hello:hello.o
@gcc hello.o -o hello
@echo make done!
hello.o:hello.c
@gcc -c hello
@echo make done!

变量定义

简单赋值 ( := ) 编程语言中常规理解的赋值方式,只对当前语句的变量有效。

递归赋值 ( = ) 赋值语句可能影响多个变量,所有目标变量相关的其他变量都受影响。(相当于C++中的引用)

条件赋值 ( ?= ) 如果变量未定义,则使用符号中的值定义变量。如果该变量已经赋值,则该赋值语句无效。(只能定义未被定义过的变量)

a1 := a.o
a1 ?= b.o

定义无效,因为前面已经定义过了

追加赋值 ( += ) 原变量用空格隔开的方式追加一个新值。(和C语言+=类似)

a1 = a.o;
a1 += b.o;

a1 = a.o b.o

特殊字符

举例说明

TARGET?=demo
OBJS:=main.o add.o sub.o
CC:=gcc
CFLAGS:= -c -o
CFLAGSs:=-o
( T A R G E T ) : (TARGET): (TARGET):(OBJS)
$(CC) $(OBJS) $(CFLAGSs) $(TARGET)
%.o:%.c
$(CC) $< $(CFLAGS) $@
clean:
rm $(OBJS) $(TARGET)

  • $(CC) $< $(CFLAGS) $@

多用前三个

  • $@ 表示目标文件名称,包含扩展名
  • $^ 表示所有的依赖文件,以空格隔开,不重复
  • $< 表示第一个依赖文件的名称
  • $+ 表示所有的依赖文件,空格隔开,可以重复
  • $* 表示目标文件的名称,不包含扩展名
  • $? 依赖项中,所有比目标文件新的依赖文件

伪指令

存在意义

  • 在Makefile中,.PHONY后面的target表示的也是一个伪造的target, 而不是真实存在的文件target,注意Makefile的target默认是文件。
  • 如果有相同的文件名,如clean,会继续执行伪指令

实际运用

  • .clean

    .PHONY:clean
    clean:
    rm -rf *.o test

    • 清除文件:make clean
  • .install

    .PHONY: install
    install:
    mkdir $(test_dir)
    cp test $(test_dir)

    • 行命令”make install“后,Make会顺序执行命令”mkdir $(test_dir)“和”cp test $(test_dir)“,把test文件复制到test_dir变量指定的目录中去
  • .uninstall

    .PHONY: uninstall
    uninstall:
    rm -rf $(test_dir)

    • 把指定的目录以及目录中的文件全部删除
  • .all

    .PHONY: all
    all: test $(obj)

    • Make会把all当成最终的目标。由于伪目标和真实目标一样都有依赖文件

通配符

Makefile中的通配符:*和%

    • 表示所有一类文件

      test:*.c
      gcc -o $@ $^
      #所有的.c文件

  • %(特殊字符的举例)

    • test:test.o test1.o
      gcc -o $@ $^
      %.o:%.c
      gcc -o $@ $^

      “%.o” 把我们需要的所有的 “.o” 文件组合成为一个列表,从列表中挨个取出的每一个文件,“%” 表示取出来文件的文件名(不包含后缀),然后找到文件中和 "%"名称相同的 “.c” 文件,然后执行下面的命令,直到列表中的文件全部被取出来为止。

条件判断

ifeq

  • 判断参数是否不相等,相等为 true,不相等为 false。

ifneq

  • 判断参数是否不相等,不相等为 true,相等为 false。

ifdef

  • 判断是否有值,有值为 true,没有值为 false。

ifndef

  • 判断是否有值,没有值为 true,有值为 false。

文件查找

VPATH 和 vpath

  • 区别

    • VPATH 是变使用时需要指定文件的路径;vpath 是关键字,搜索的时候不仅需要加上文件的路径,还需要加上相应限制的条件。

      VPATH 是变量,更具体的说是环境变量,Makefile 中的一种特殊变量,使用时需要指定文件的路径;vpath 是关键字,按照模式搜索,也可以说成是选择搜索。搜索的时候不仅需要加上文件的路径,还需要加上相应限制的条件。

  • VPATH

    VPATH = /home/b
    obj = a.o b.o
    .PHONY : all
    all:test ( o b j ) t e s t : (obj) test: (obj)test:(obj)
    cc -o test $(obj)

    • 格式:VPATH := /src:/car

      先搜索/src,再搜索/car
      可以这样理解,把 src 的值赋值给变量 VPATH

    • 注意:无论定义了多少路径,makefile都会首先在当前目录下寻找,找到了,则不会到VPATH继续寻找

  • vpath

    • 格式:vpath 模式 目录:目录…
    • vpath test.c /src :/car
  • 其他

    • vpath test.c

      • 意思是清除符合文件 test.c 的搜索目录
    • vpath

      • vpath 单独使的意思是清除所有已被设置的文件搜索路径

常用函数

wildcard

  • SRC = $(wildcard .c ./foo/.c)

    搜索当前目录及./foo/下所有以.c结尾的文件,生成一个以空格间隔的文件名列表,并赋值给SRC.当前目录文件只有文件名,子目录下的文件名包含路径信息,比如./foor/bar.c。

patsubst

Makefile 内容

all:
@echo $(patsubst %.c,%.o,programA.c programB.c)

bash 中执行 make

$ make
programA.o programB.o

  • $(patsubst ,, )

    功能: 查找 中的单词(单词以"空格", “tab”, "换行"来分割) 是否符合 , 符合的话, 用 替代.

notdir

Makefile 内容

all:
@echo $(notdir /home/a.c ./bb.c …/c.c d.c)

bash 中执行 make

$ make
a.c bb.c c.c d.c

  • $(notdir <names…>)

功能: 从文件名序列 中取出非目录部分
返回: 文件名序列 中的非目录部分

XMind: ZEN - Trial Version

猜你喜欢

转载自blog.csdn.net/m0_52592798/article/details/125983391