Linux-Makefile与make命令

发布时间 2023-11-22 20:41:08作者: (喜欢黑夜的孩子)

Makefile命令

 

makefile文件和make工具的作用
make它能够通过查找文件中记录的被修改过的文件根据依赖关系对这些文件来单独编译,达到快速编译多个文件的过程。

Make的执行过程

当控制台终端执行make命令以后,它就会去寻找Makefile文件并执行文件中的第一个目标的命令。例子中第一个目标targetA要执行,它需要她的依赖文件targetB,targetC,所以编译器会先去尝试执行targetB,targetC的命令,执行完依赖文件的命令以后执行targetA的命令

例子

    

   

同样的也能够单独执行构建一个目标的命令
sudo make :执行Makefile中所有目标命令
make targetB:执行Makefile文件中targetB的目标命令
注意:当要执行的目标文件已经存在/最新时,目标文件的命令不会被执行

 

Makefile主要知识点

1.makefile 三要素  :目标,依赖文件,命令

          

2.Makefile变量  :为了快速记录长而复杂的命令,同时能够通过改变Makefile变量提高Makefile文件的通用性

3.分支判断:根据条件执行不同命令
4.头文件依赖:工程包括很多文件
5.隐含规则:根据makefile的隐含规则减少编写makefile的工作量
6.自动化变量+模式规则
7.makefile函数:提供了很多现成的功能函数

8.伪目标   :当设置了伪目标后,会无视文件的情况每次make都执行

 

简单makefile文件:后续会更新更加通用的Makefile文件

 

自动化变量+模式规则:重点在于三个赋值

自定义变量中的延迟赋值----------------(只有调用的时候才会真的赋值)

立即赋值-------------------------------------(命令在执行的时候变量值就改变了)

空赋值----------------------------------------(只有变量为空的时候才能被赋值)

 追加赋值------------------------------------(赋值的值不会覆盖原来值而是在后面追加数据)

 

三个自动化变量,多加利用可以写出通用Makefile文件

 

追加了Makefile变量之后的Makefile文件,可以通过修改变量的值来快速产生新的Makefile文件

 

 

Makefile中默认使用c文件生成o文件,因此生成o文件代码可以不写

 

 Makefile的条件分支

 

Makefile的常见文件

 

去掉文件的目录只显示文件的文件名

$(notdir <names>)

 

获取匹配模式文件名函数:wildcard

$(wildcard PATTERN)

  • 该函数列出当前目录下所有符合 PATTERN 模式的文件名。
  • 返回值为当前目录下所有符合 PATTERN 模式的文件名,它们以空格分隔。
  •  

    上面的式子会返回当前目录所有的c文件

 

 Makefile的for循环

 $(foreach <var>,<list>,<text>)

下面的代码会将a,b,c,d目录下所有文件名都存在files文件中

 

 

模式字符串替换函数:patsubst

$(patsubst <pattern>,<replacement>,<text>)  :会识别test中的文件是否符合模式,如果符合,文件会被替换为新的模式

c文件都被替换成立o文件

 

 

野火教学视频中的通用Makefile文件...........真的有必要这么复杂吗.............

ARCH ?= x86

ifeq ($(ARCH),x86)
        CC=gcc
else
        CC=arm-linux-gnueabihf-gcc
endif

TARGET=mp3
#OBJS=main.o mp3.o
BUILD_DIR=build
SRC_DIR=module1 module2
INC_DIR=include
CFLAGS=$(patsubst %,-I%,$(INC_DIR))
INCLUDES=$(foreach dir,$(INC_DIR),$(wildcard $(patsubst)/*.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 $@

#main.o:
#    gcc -c main.c -o main.o

#mp3.o:
#    gcc -c mp3.c -o mp3.o

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

.PHONY:clean create_build

clean:
    rm -r $(BUILD_DIR)

create_build:
    mkdir -p $(BUILD_DIR)