-- TOC --
估计mychar驱动已经差不多了,由于有驱动,以及几个测试程序,我将他们整合在一个makefile中,故此总结一篇makefile的规则。
$ cat Makefile
obj-m := mychar.o
PWD := $(shell pwd)
PREFIX := /home/xinlin/sources
SRC := $(PREFIX)/linux-5.14.14
CC := gcc
CFLAGS := -Wall -Wextra -I$(PREFIX)/linux-5.14.14/include
# make is make all, this is default target
.PHONY: all
all: mychar others
.PHONY: mychar
mychar:
$(MAKE) -C $(SRC) M=$(PWD) modules
OTHERS := showcmd try_ioctl try_write eat_mem
.PHONY: others
others: $(OTHERS)
# here use built-in pattern rules to save typing
# make -pn | less
showcmd.o \
try_ioctl.o \
try_write.o \
eat_mem.o: mychar.h
#showcmd: showcmd.c mychar.h
# $(CC) $(CFLAGS) $< -o $@
#
#try_ioctl: try_ioctl.c mychar.h
# $(CC) $(CFLAGS) $< -o $@
#
#try_write: try_write.c mychar.h
# $(CC) $(CFLAGS) $< -o $@
#
#eat_mem: eat_mem.c mychar.h
# $(CC) $(CFLAGS) $< -o $@
# char @ to make command invisible
# char - to ignore command error and continue
.PHONY: clean
clean:
rm -f *.o *.ko *.cmd *.dwo *.mod *.mod.c Module.symvers modules.order
rm -f .m* .M*
rm -f $(OTHERS)
#@rm -f *.o *.ko *.cmd *.dwo *.mod *.mod.c Module.symvers modules.order
#@rm -f .m* .M*
#@rm -f $(OTHERS)
#-rm *.o *.ko *.cmd *.dwo *.mod *.mod.c Module.symvers modules.order
#-rm .m* .M*
#-rm $(OTHERS)
知识点:
:=
赋值的variable,直接在赋值的时候,展开右边的变量引用($);而=
赋值,是在command script中再展开;@
用在command前,可以让command在make过程中不显示;-
用在command前,如果command执行出错,比如exit不为0,make直接忽略,继续后面的执行;\
换行;make -pn abc| less
查看(abc是个不存在target,在没有makefile的目录下可以不需要);上面的makefile就用到了几个这样的rule:# default
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
# default
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
%: %.o
# recipe to execute (built-in):
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
所以,others这个target,定义的CC和CFLAGS,都会被builtin pattern rule使用。.c会先编译成.o,然后.o再链接成bin文件。注意,.o文件增加了对mychar.h文件的依赖,因此mychar.h文件如果更新,所有.o都会被更新,然后接着更新bin文件。
make定义了一些automatic variable,每当一个rule matched,这些automatic variable都会被update,并可以在command script中使用:
$@
:表示target;
$<
:表示从左到右第一个prerequisite;
$^
:表示全部prerequisite,去重后的;
$+
:表示全部prerequisite,没去重的;
$?
:表示那些比target更新的prerequisite;(newer than target)
好了,全套mychar驱动代码:https://github.com/xinlin-z/mydriver/tree/main/mychar
本文链接:https://cs.pynote.net/sf/linux/dd/202201131/
-- EOF --
-- MORE --