Makefile学习笔记:$(A) $^ $@和%,条件分支,常见函数

Makefile的三要素:

目标:依赖

        命令

例如,

hello:main.o hello.o
    gcc main.o hello.o -o hello
main.o:main.c
    gcc -c main.c -o main.o
hello.o:hello.c
    gcc -c hello.c -o hello.o

.PHONY:clean

clean:
    rm hello

利用Makefile可以高效地管理项目。我们可以用变量优化一下这个Makefile文件。

关于Makefile一些常见的变量:系统变量、自定义变量、自动化变量。

自动化变量:$<指第一个依赖文件

                        $^指全部的依赖文件

                        $@指目标

系统变量:如CC、AS、MAKE等,值为cc、as、make。

自定义变量:自己定义的变量,如A、B等。
 

A=123

B=$(A)

A=456

.PHONY:all

all:

        echo"$(B)"

此Makefile文件执行make命令以后结果为456。因为此处的A=123是延迟赋值,只有当变量调用时等号才会将值赋给自定义变量B。:=是立即赋值。?=是空赋值,当变量值为空时赋值才有效。+=是追加赋值,在已经定义的值后面追加,例如:

A=123
A+=456

.PHONY:all

all:

        echo"$(A)"

执行make命令结果为123 456.

下面演示用变量优化文章开头的Makefile文件:

CC=gcc
target=hello
obj=main.o hello.o

$(target):$(obj)
    $(CC) $^ -o $@
main.o:main.c
    $(CC) -c main.c -o main.o
hello.o:hello.c
    $(CC) -c hello.c -o hello.o

.PHONY:clean

clean:
    rm hello

这样写就变得优雅(看不懂)了起来!

在Makefile中%的作用是匹配任意多个非空字符,类似于shell中的*(通配符)。

继续优化Makefile:

CC=gcc
target=hello
obj=main.o hello.o

$(target):$(obj)
    $(CC) $^ -o $@
%.o:%.c
    $(CC) -c $< -o $@

.PHONY:clean

clean:
    rm hello

条件分支:

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

target=hello
obj=main.o hello.o

$(target):$(obj)
    $(CC) $^ -o $@
%.o:%.c
    $(CC) -c $< -o $@

.PHONY:clean

clean:
    rm hello *.o

执行make ARCH=arm后,hello应用程序就是由arm-linux-gnueabihf-gcc编译的了。

常见函数:

patsubst、notdir、wildcard、foreach

patsubst示例:

#Makefile_1
.PHONY:all

all:
    echo "$(patsubst %.c, %.o ,x.c.c bar.c)"

执行make -f Makefile_1命令后,结果为x.c.o bar.o。patsubst函数的功能就是指定模式替换。(这里需要注意的是,patsubst函数完成的是模式字符串替换,获取到的和输出的都是字符串,执行完函数以后并不会改变原来文件的后缀!)

notdir示例:

#Makefile_2
.PHONY:all

all:
    echo "$(notdir src/fo.c bar.c)"

执行make -f Makefile_2命令后,结果为fo.c bar.c。patsubst函数的功能就是删除文件的路径,只保留文件名,没有路径则不做改变。

wildcard示例:

#Makefile_3
.PHONY:all

all:
    echo "$(wildcard *.c)"

执行make -f Makefile_2命令后,结果为x.c xxx.c。wildcard函数的功能就是获取当前目录下匹配模式的文件名。

foreach示例:

#Makefile_4

dirs:=a b c d
files:=$(foreach dir,$(dirs),$(wildcard $(dir)/*))

.PHONY:all

all:
    echo "$(files)"

上述语句实现的功能等价于files:=$(wildcard a/* b/* c/* d/*)。foreach函数会遍历dirs中的所有内容并赋值给dir,dir参与wildcard $(dir)/*的运算。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值