MakeFile从入门到精通(5)

MakeFile的条件判断

关键字

ifeq,else,endif   ,ifneq

使用

条件语句从ifeq开始,括号与关键字用空格隔开

应用场景:可以灵活的功能强大,比如一个一个软件希望编译为debug或Release模式。可以通过条件判断变量实现。

.PHONY:all

DEBUG = true
ifeq ($(DEBUG),true)
VERSION = debug
else
VERSION = release
endif
all:
        @echo "build   $(VERSION) mode"

注意:ifeq 后面有个空格  DEBUG  有个空格  好像有时候没有空格 make时候会报错。

我们可以去掉DEBUGE 后面的    true 再make就会输出release如下

.PHONY:all

DEBUG =
ifeq ($(DEBUG),true)
VERSION = debug
else
VERSION = release
endif
all:
        @echo "build   $(VERSION) mode"

make输出:build   release  mode

那么我们就可以再ifeq下面定义编译器了,如下:

.PHONY:all

DEBUG =
ifeq ($(DEBUG),true)
VERSION = debug
CC = gcc  -g
else
VERSION = release
cc = gcc
endif
hello:hello.c
        @echo "build   $(VERSION) mode"
        $(CC) -o  $@   $^
clean:
        rm  hello
                   

我们就新建一个hello.c文件

#include <stdio.h>

int main()
{
        printf("hello world:\n");
        return 0;
}

执行make输出:build   release  mode  

gcc -o   hello   hello.c

同样我们将DEBUG改成 true

.PHONY:all

DEBUG = true
ifeq ($(DEBUG),true)
VERSION = debug
CC = gcc  -g
else
VERSION = release
cc = gcc
endif
hello:hello.c
        @echo "build   $(VERSION) mode"
        $(CC) -o  $@   $^
clean:
        rm  hello

执行make:输出build   debug  mode  

gcc  -g  -o  hello   hello.c
如果提示:make: 'hello' is up to date. 请先clean一下,还有需要注意的就是DEBUG  一些目标变量后面的空格键。

我刚开始好多错误,就是因为要么多一个空格要么少一个空格,特别是条件变量需要判断的变量,赋值的地方等。

还有注意:如果是arm下面CC 就需要可能等于ramcc等编译器,判断后面的空格等。

 

=============================================================================================

函数:函数再Makefile当中也会被大量使用,除了规则就是函数和变量被大量的使用了。而大量的变量和函数被使用的目的也是为规则服务的。为了更好的构建makefile的依赖关系。所以我们必须掌握常用的函数以及搞清楚。这样在分析复杂的makefile才能够游刃有余。

一般我们百度都能找到搜索到MakeFile的中心手册,里面列举了很多函数。

我这里总结一下函数怎么使用使用方法,另我也不推荐大家去学书“深度理解软件构造原理与最佳实战”,对软件底层构造有深度理解。虽然好但是不能但是太耗时。

我们常用的函数有:1,文本处理函数。2,文件名处理函数

看一个例子:

文本处理函数

.PHONY:all
SRCS = player.c lcd.c usb.c media.c hello.h main.txt
OBJS = $(subst .c,.o,$(strip $(SRCS)))
DEPS = $(patsubst %.c,%.d,$(SRCS))
DEPS2 = $(SRCS:.c=.d)
FIND = $(findstring usb,$(SRCS))
FILTER = $(filter %.c %.h, $(SRCS))
all:
        @echo "OBJS = $(OBJS)"  
        @echo "DEPS = $(DEPS)"
        @echo "DEPS2 = $(DEPS2)"
        @echo "FIND = $(FIND)"
        @echo "FILTER = $(FILTER)"
                                  

 

$(subst      .....);//字符串替换函数后面是它的参数 

$(strip(SRCS)) ;//去空格就是把SRCS的后面的字符串的.c后面的空格去掉。$

$(patsubst ....);//模式替换函数 使用的是% 功能与subst类似但是支持模糊遍历了。就是把里面的所有.c文件替换成.d文件。后面的参数就是字符串。同样后面的DEPS2 的写法是简写也可以的。

findstring 是字符串查找 从后面的参数$(SRCS)字符串查找usb这个字符串。找到就返回找不到就返回结果。如果空的话就返回空就是没有找到。

$(filter ...)//就是过滤从后面的参数$(SRCS)中的字符串中过滤.c  .h文件。过滤出来返回给后面的变量。

还有其他的函数大家自己以后学习吧。

执行make输出如下:

OBJS = player.o lcd.o usb.o media.o hello.h main.txt
DEPS = player.d lcd.d usb.d media.d hello.h main.txt
DEPS2 = player.d lcd.d usb.d media.d hello.h main.txt
FIND = usb
FILTER = player.c lcd.c usb.c media.c hello.h

可以 看出OBJS 后面.c 变成了 .o

DEPS 后面变成了.d了。DEPS2 与DEPS 效果一样。为了简单可以按照下面DEPS2这样写。

filter-out与filter效果相反的,除了过滤除去还可以相反的保留下来其他过滤出去。

接下来我们再看看文件名函数,:即处理文件,文件名,文件名前缀,后缀,连接等

makefile内容如下:

.PHONY:all
LIB = /home/hello/libhello.a
LIB1 = $(dir $(LIB))
LIB2 = $(notdir $(LIB))
LIB3 = $(suffix $(LIB))
LIB4 = $(basename $(LIB))
LIB5 = $(addsuffix .c,$(LIB4))
LIB6 = $(addprefix /usr/lib/,$(LIB2))
SRCS = $(wildcard *.c)
all:
	@echo "LIB1 = $(LIB1)"
	@echo "LIB2 = $(LIB2)"
	@echo "LIB3 = $(LIB3)"
	@echo "LIB4 = $(LIB4)"
	@echo "LIB5 = $(LIB5)"
	@echo "LIB6 = $(LIB6)"	
	@echo "SRCS = $(SRCS)"

执行make输出如下:

LIB1 = /home/hello/
LIB2 = libhello.a
LIB3 = .a
LIB4 = /home/hello/libhello
LIB5 = /home/hello/libhello.c
LIB6 = /usr/lib/libhello.a
SRCS = 3.c hello.c main.c
因为我们的最后echo就输出了这么多,我们可以看出。

LIB1 取目录 LIB2去除了目录。

LIB3取后缀。LIB4取前缀  

LIB5 添加一个后缀

LIB6 对LIB2添加了一个目录。

 SRCS最后wildcard 函数是列举当前目录下的所有的.c文件。

除此之外还有其他常见的函数:特别重要的是foreach函数相当于C语言的for循环。

还有shell函数可以直接使用shell命令。

foreach例子如下makfile内容

  1 
  2 A = 1 3 4 5 6 7 8 9
  3 B = $(foreach i,$(A),$(addprefix 0.,$(i)))
  4 C = $(foreach i,$(A),$(addsuffix .0,$(i)))
  5 
  6 
  7 all:
  8         @echo "A = $(A)"
  9         @echo "B = $(B)"
 10         @echo "C = $(C)"

注意上面的括号配对,上面的例子的第三行的foreach 就是 对字符串A 的字符依次赋值给i,那么对i进行什么操作呢?由后面的参数决定,我们上面说了addprefix 加个前缀0.

后面的第四行一样是加个后缀 .0   最后输出

我们执行make 输出如下:

A = 1 3 4 5 6 7 8 9
B = 0.1 0.3 0.4 0.5 0.6 0.7 0.8 0.9
C = 1.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0

我们接下来看看shell函数的使用:

makefile内容如下:

  1 .PHONY:all clean
  2 $(shell mkdir -p s1)
  3 $(shell mkdir -p s2)
  4 all:
  5         @echo "hello world"
  6 clean:
  7         rm -r s1 s2

就是在makefile里面直接运行shell命令,直接加$(shell  ...)就可以了。

我们执行make输出如下:hello  world  再ls查看已经有了s1  s2 文件夹了。


函数这东西就是最后查手册。。makefile中文手册自己看吧。自己慢慢练习吧

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值