foreach 函数
$(foreach ,,
意思从list变量取一个到var 执行text的语句,循环取list直到取完。
names := a b c d
files :=
(
f
o
r
e
a
c
h
n
,
(foreach n,
(foreachn,(names),$(n).o)
file 最后就是等于 a.o b.o c.o d.o
还有一个常用的手法,获取当前目录下的所有.c文件
SPATH = .
SOURCES = $(foreach dir, $(SPATH), $(wildcard $(dir)/*.c))
如果需要递归子目录的话可以用shell函数列出目录
便利深度为3级子目录
DIRS := $(shell find . -maxdepth 3 -type d)
1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符
有两个目录dir 以及dir/subdir
dir下有a.c b.c dir/subdir下有sub.c
在dir下的makefile中如下代码
src=
(
w
i
l
d
c
a
r
d
∗
.
c
.
/
s
u
b
d
i
r
/
∗
.
c
)
中间以空格分隔
d
i
r
=
(wildcard *.c ./subdir/*.c)中间以空格分隔 dir=
(wildcard∗.c./subdir/∗.c)中间以空格分隔dir=(notdir
(
s
r
c
)
)
o
b
j
=
(src)) obj=
(src))obj=(patsubst %.c,%.o,$(dir) )吧dir中符合后缀.c替换成.o
srca.c b.c ./subdir/sub.c
dira.c b.c sub.c 去除路径
obj==a.o b.o sub.o
obj的操作也可以这样写
或者可以使用
obj=$(dir:%.c=%.o)
打印
makefile
中使用echo必须在目标执行的里面使用
如果想要在其他地方打印必须使用调试信息有三档
info info信息,不打印信息所在行号
warning 会打印行号
error 停止当前makefile的编译
$(error “error: this will stop the compile”)
比如
echo aaa xxxx不可以打印报错
$(error “aaa”) 可以,但是会停止编译
all:
echo ‘aaaa $(SOURCES)’
取值
在makefile中用小括号$(xxx),而shell中是用{} ${XXX_KaTeX parse error: Expected 'EOF', got '}' at position 4: abc}̲ 这种。 在makefile中…前缀,显示bash变量使用KaTeX parse error: Can't use function '$' in math mode at position 25: … @for dir in $̲(SUB_SRC); do \…{dir};
if [ “$$?” != “0” ]; then
exit 1;
fi;
done
判断
ifeq (
(
a
r
c
h
)
,
X
86
)
e
l
s
e
i
f
e
q
(
(arch), X86) else ifeq (
(arch),X86)elseifeq((TARGET_ARCH), x86)
else
endif
/------------------
ifeq ($(strip $(arch)), $(filter $(arch), arm9 x86 mips))
LD_FLAGS =xxxx
endif
export
make -C xxx 表示进到摸个目录下执行make 这样的关系是有层级关系的,在顶层makefile中export的变量是可以传导子makefile中的
在shell中export的变量 同时通过shell中执行make后的子makefile依然可以使用这个变量
gcc 编译 werror
gcc 加上-Werror 会出现很多严格的报错
比如定义未使用
defined but not used [-Werror=unused-function]
解决办法,严格执行gcc的提示去除无效代码
投机临时使用
编译时过滤忽略
@$(CC) $(C_CFLAGS) -c $< -o $@ -Wno-unused-function
makefile ko换名引用多个.o
使用该文件编译内核模块。
正常情况下,Makefile文件内容如下:
ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
(
i
n
f
o
"
2
n
d
"
)
e
l
s
e
K
D
I
R
:
=
/
l
i
b
/
m
o
d
u
l
e
s
/
(info "2nd") else KDIR := /lib/modules/
(info"2nd")elseKDIR:=/lib/modules/(shell uname -r)/build
PWD:=$(shell pwd)
all:
$(info “1st”)
make -C
(
K
D
I
R
)
M
=
(KDIR) M=
(KDIR)M=(PWD) modules
clean:
rm -f *.ko *.o .mod ..cmd *.symvers *.mod.c *.mod.o .order .hello
endif
执行make命令,生成hello.ko文件。
执行sudo insmod hello.ko命令,安装该模块。
执行lsmod命令,查看安装的模块。就会看到第一行的就是hello模块。
但是,如果想自定义模块名称为xmodule,而不是默认的hello,如何实现呢?方法如下:
在Makefile中重命名obj-m并将obj-m的依赖关系设置为原始模块(hello)
修改后的Makefile文件内容如下:
ifneq ($(KERNELRELEASE),)
obj-m:=xmodule.o
xmodule-objs := hello.o
(
i
n
f
o
"
2
n
d
"
)
e
l
s
e
K
D
I
R
:
=
/
l
i
b
/
m
o
d
u
l
e
s
/
(info "2nd") else KDIR := /lib/modules/
(info"2nd")elseKDIR:=/lib/modules/(shell uname -r)/build
PWD:=$(shell pwd)
all:
$(info “1st”)
make -C
(
K
D
I
R
)
M
=
(KDIR) M=
(KDIR)M=(PWD) modules
clean:
rm -f *.ko *.o .mod ..cmd *.symvers *.mod.c *.mod.o .order .hello
endif
将obj-m设置为xmodule.o,并使xmodule.o依赖于hello.o.
执行make命令后,生成xmodule.ko, 而不是hello.ko,
安装命令: sudo insmod xmodule.ko
查看命令:lsmod,就会看到被安装名为xmodule的模块。