Makefile-基础

Makefile


通常来说Makefile和make命令是配合使用的。大型项目通过Makefile来组织编译,通过Makefile清晰各种库和代码的依关系

Makefile文件中的命令有一定规范,在文件编写好之后即可执行一条make命令编译整个工程。不同的make可能会有所不同,在语法上也会有所区别,但是基本思想类似,最广泛的是GUNmake。

GUN make的工作方式


  1. 读入主Makefile(主Makefile中可以引用其他的Makefile)
  2. 读入被include的其他Makefile
  3. 初始化文件中的变量
  4. 推导隐晦规则,并分析所有规则
  5. 为所有的目标文件创建依赖关系链
  6. 根据依赖关系,决定那些目标要重新生成
  7. 执行生成命令

语法规则


目标 . . . :依赖 . . .

​ 命令1

​ 命令2

或者

目标 . . . :依赖 . . .;命令1

​ 命令2

​ 命令3

Makefile不会关心命令如何执行的,仅仅是会去执行所有定义的命令,和输入命令行是一样的效果

  • 目标即生成的文件:如果文件的更新时间晚于依赖文件更新时间,说明依赖文件没有改动,目标文件不需要重新编译,否则会重新编译并更新目标文件。
  • 终极文件:默认情况下Makefile的第一个目标即为终极文件
  • 依赖:即目标文件由那些文件生成
  • 命令:即通过执行命令由依赖文件生成目标文件。注意每条命令之前必须有一个tab保持缩进,这是语法要求。
  • all:Makefile文件默认只生成第一个目标文件即完成翻译,但是可以通过all指定需要生成的目标文件
  • 显示规则:说明如何生成一个或者多个目标文件(包括生成的文件,文件的依赖文件,生成的命令)
  • 隐晦规则:make的自动推导功能所执行的规则
  • 变量定义:Makefile中定义的变量
  • 文件指示:Makefile中引用其他的Makefile;指定Makefile中有效的部分;定义一个多行命令
  • 注释:Makefile只有行注释“#”,如果要使用或者输出“#”字符,需要进行转义,“\#”

变量覆盖override


作用是使Makefile中定义的变量能够覆盖make命令参数中指定的变量

语法:

override variable = value

# Makefile内容 (没有用override)
SRCS := programA.c programB.c programC.c
 
all:
    @echo "SRCS: " $(SRCS)
 
# bash中运行make
$ make SRCS=nothing
SRCS:  nothing
 
#################################################
 
# Makefile内容 (用override)
override SRCS := programA.c programB.c programC.c
 
all:
    @echo "SRCS: " $(SRCS)
 
# bash中运行make
$ make SRCS=nothing
SRCS:  programA.c programB.c programC.c

变量


$符号表示取变量的值,当变量名多于一个字符时,使用"( )"

$^表示所有的依赖文件

$@表示生成的目标文件

$<表示第一个依赖文件

目标变量


作用是使变量的作用域仅限于这个目标(target),而不像之前例子中定义的变量,对整个Makefile都有效

target :: variable-assignment

# Makefile 内容
SRCS := programA.c programB.c programC.c
 
target1: TARGET1-SRCS := programD.c
target1:
    @echo "SRCS: " $(SRCS)
    @echo "SRCS: " $(TARGET1-SRCS)
 
target2:
    @echo "SRCS: " $(SRCS)
    @echo "SRCS: " $(TARGET1-SRCS)
 
# bash中执行make
$ make target1
SRCS:  programA.c programB.c programC.c
SRCS:  programD.c
 
$ make target2     <-- target2中显示不了 $(TARGET1-SRCS)
SRCS:  programA.c programB.c programC.c
SRCS:

变量赋值


  1. “=”是最普通的等号,在Makefile中使用“=”进行赋值,变量的值是整个Makefile中最后被指定的值
  2. “:=”表示直接赋值,赋予当前位置的值
  3. “?=”表示如果该变量没有被赋值,则进行赋值
  4. “+=”和平时写代码的理解是一样的,表示将符号后面的值添加到前面的变量上

预定义变量


CC:c编译器的名称,默认值为cc

回显问题:Makefile中的命令都会被打印出来。如果不想打印命令部分,可以使用@去除回显

函数


规则中的通配符

* ::表示一个或者多个字符

? ::表示任意一个字符

[…] ::ex.[abcd]表示a,b,c,d中任意一个字符[ ^ abcd]表示除a,b,c,d以外的字符,[0-9]表示 0~9中任意一个数字
:: 表示用户的home目录

通配符

SRC = $(wildcard ./*.c)

匹配目录下所有.c文件,并赋值给SRC变量

OBJ = $(patsubst %.c, %.o, $(SRC))

函数有三个参数,是取出SRC中的所有值,然后将.c转成.o最后赋值给OBJ变量

路径搜索


当一个Makefile中涉及了大量的源文件时(这些源文件和Makefile极有可能不在同一个目录中)

这是,最好将源文件的路径明确在Makefile中,便于编译时直接查找,Makefile中国有一个特殊的变量VPATH就是完成这个功能的指定VPATH之后,如果当前目录中没有找到响应文件或者依赖的文件,Makefile回到VPATH指定的路径中再去查找

VPATH使用方法

vpath <directories>            :: 当前目录中找不到文件时, 就从<directories>中搜索
vpath <pattern> <directories>  :: 符合<pattern>格式的文件, 就从<directories>中搜索
vpath <pattern>                :: 清除符合<pattern>格式的文件搜索路径
vpath                          :: 清除所有已经设置好的文件路径
# 示例1 - 当前目录中找不到文件时, 按顺序从 src目录 ../parent-dir目录中查找文件
VPATH src:../parent-dir   
 
# 示例2 - .h结尾的文件都从 ./header 目录中查找
VPATH %.h ./header
 
# 示例3 - 清除示例2中设置的规则
VPATH %.h
 
# 示例4 - 清除所有VPATH的设置
VPATH

伪目标


伪目标只是一个标签,clean是个伪目标没有依赖文件,只有用make来调用的时候才会执行

当目标下拥有和make命令同名的文件时,执行make命令就会出现错误,解决方法就是使用伪目标。

SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
 
ALL: hello.out
 
hello.out: $(OBJ)
        gcc $< -o $@
 
$(OBJ): $(SRC)
        gcc -c $< -o $@
 
clean:
        rm -rf $(OBJ) hello.out
 
.PHONY: clean ALL

其他常用功能


代码清理clean

可以编译一条clean语句,清理所有make命令产生的所有文件

SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
 
ALL: hello.out
 
hello.out: $(OBJ)
        gcc $< -o $@
 
$(OBJ): $(SRC)
        gcc -c $< -o $@
 
clean:
        rm -rf $(OBJ) hello.out

Makefile命令前缀


有三种前缀

无前缀:输出执行的命令以及命令执行的结果,出错停止执行

前缀@:只输出命令执行的结果,出错停止执行

前缀-:命令出错的话忽略错误,继续执行

引用其他的Makefile


#include < filename >(filename 可以包括通配符和路径)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值