Makefile常用参数

一、make编译过程
//预处理,#开头的代码全被解决掉(预编译,包含库,宏定义等等)hello.i上千行.
gcc  -E hello.c >> hello.i

//编译,检查语法错误,生成.s文件,汇编代码,大概26行.
gcc -S hello.i

//汇编。产生后缀.o的object目标文件,二进制,不可以运行,缺少库信息.
gcc -c hello.s
  • 总结:预处理.i => 编译.s => 汇编.o => 链接
二、常见参数

-f :执行make的时候,带上-f <文件名>参数,来指定make命令从哪里读取makefile文件;而如果我们不显式指定,则make就会在当前目录下依次查找名字为GNUmakefile, makefile,和 Makefile的文件来作为其makefile文件.

- :让make忽略该命令的错误,例如,通常在Makefile中使用-include来代替include,忽略由于包含文件不存在或者无法创建时的错误提示,make继续执行。

@ :关闭回显。不显示命令,只显示结果.而make参数-s--slient则是禁止所有执行命令的显示.

$(shell pwd) :获取当前目录的绝对路径 例如:-include $(shell pwd)/src/C_SRC

?= :变量在之前没有赋值的情况下才会对这个变量进行赋值.
:= :直接展开定义变量.
= :递归展开,可能陷入无限循环.
$@ "代表规则中的目标文件名.
$< "代表规则的第一个依赖的文件名.
$^ "代表规则中所有依赖文件的列表,文件名用空格分割.

如果一行以Tab字符开始,make程序将此行作为一个命令行来处理.

三、内嵌函数
1、filter 过滤

C_SRC = $(filter %.c, $(SOURCES))

CPP_SRC = $(filter %.cpp,$(SOURCES))

替换引用

C_OBJS = $(C_SRCS:%.c=../obj/%.o)

CPP_OBJS = $(CPP_SRCS:%.cpp=../obj/%.o)

2、wildcard 扩展通配符

$(wildcard PATTERN) :列出当前目录下所有符合模式“PATTERN”格式的文件名.

$(wildcard *.c) 返回值为当前目录下所有.c源文件列表.

C_SRC = $(wildcard *.c) $(wildcard src/*.c) 获取根目录、子目录src下的所有.c源文件。

3、patsubst 替换通配符

$(patsubst <pattern>,<replacement>,<text> ) :查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换.

$(patsubst %.c,%.o, a.c b.c) :把字串“a.c b.c”符合模式[%.c]的单词替换成[%.o],返回结果是“a.o b.o”

OBJS_FILE := $(patsubst %,obj/%,$(OBJS)) :把字符串 OBJS 替换到obj目录下.用于生成的目标文件统一汇总到目录下obj下.

objects := $(patsubst %.c,%.o,$(wildcard *.c)) :先使用wildcard函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表。

4、notdir 去除路径

现有如下文件结构:

  proj
    │──── pj1.c
    │──── pj2.c
    └──── src
           │─── sr1.c
           └─── sr2.c

makefile如下:

C_SRC=$(wildcard *.c ./src/*.c)
NODIR=$(notdir $(C_SRC))
OBJS=$(patsubst %.c,%.o,$(NODIR) )

all:
	@echo $(C_SRC)
	@echo $(NODIR)
	@echo $(OBJS)

输出显示:

pj1.c pj2.c ./src/sr1.c ./src/sr2.c
pj1.c pj2.c sr1.c sr2.c
pj1.o pj2.o sr1.o sr2.o
四、makefile的静态模式

静态模式规则是这样一个规则:规则存在多个目标,并且不同的目标可以根据目标文件的名字来自动构造出依赖文件。静态模式规则比多目标规则更通用,它不需要多个目标具有相同的依赖。但是静态模式规则中的依赖文件必须是相类似的而不是完全相同的。
首先,我们来看一下静态模式规则的基本语法:

targets …: target-pattern: prereq-patterns …
    COMMANDS
    ...

Each target is matched against the target-pattern to extract a part of the target name, called the stem. This stem is substituted into each of the prereq-patterns to make the prerequisite names (one from each prereq-pattern).

%从目标模式targets的目标名字中抽取一部分字符串(称为“茎”,即抽取的%匹配的部分)。使用“茎”替代依赖模式prereq-patterns中的相应部分来产生对应目标的依赖文件。例如:

objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
    $(CC) -c $(CFLAGS) $< -o $@

上例中,规则描述了所有的.o文件的依赖文件为对应的.c文件,对于目标“foo.o”,取其茎“foo”替代对应的依赖模式“%.c”中的模式字符“%”之后可得到目标的依赖文件“foo.c”。这就是目标“foo.o”的依赖关系“foo.o: foo.c”,

再例如:

SOURCES := home.c etc.c src/sr1.c  mod/mod.cpp  
C_SRCS   = $(filter %.c, $(SOURCES))
CPP_SRCS = $(filter %.cpp,$(SOURCES))

#目标文件统一输出到obj目录,字符串增加../obj/
C_OBJS   = $(C_SRCS:%.c=../obj/%.o)
CPP_OBJS = $(CPP_SRCS:%.cpp=../obj/%.o)

#构建时需要再还原回去,字符串去掉../obj/
$(C_OBJS):../obj/%.o:%.c
	@mkdir -p ../obj
	@mkdir -p $(dir $@)  #创建子目录
	$(CC) -c $(CFLAGS) $< -o $@

$(CPP_OBJS):../obj/%.o:%.cpp
	@mkdir -p ../obj
	@mkdir -p $(dir $@) 
	$(CXX) -c $(CFLAGS) $< -o $@


参考资料:
GNU make

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luuyiran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值