Linux 内核 Makefile.build 构建外部模块时的奇怪行为
Linux Kernel Makefile.build strange behavior when building external modules
我需要一些与构建外部模块相关的KBuild
实现细节建议。
Linux Kernel 5.0.0-32
这是我的 LKM
Makefile:
obj-m += pfsw.o
pfsw-objs := src/init.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
查看 scripts/Makefile.build
and printing the debug output with -d
option I found that the target of this makefile being executed is __build
的实现:
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
@:
因为我正在构建外部 LKM,所以唯一的先决条件是 $(obj-m)
和 $(modorder-target)
。我从数据库中获取了它们的值:
obj-m := /home/memyself/lkm/procfs_write_perm/pfsw.o
modorder-target := /home/memyself/lkm/procfs_write_perm/modules.order
所以要执行 __build
必须首先构建先决条件 /home/memyself/lkm/procfs_write_perm/pfsw.o
。在 Makefile.build
中定义了以下 $(obj)/%.o:
模式规则:
$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
我添加了调试输出来打印目标自动变量的名称:
$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
@echo "$@"
$(call cmd,force_checksrc)
$(call cmd,force_check_kmsg)
$(call if_changed_rule,cc_o_c)
并期望打印 /home/memyself/lkm/procfs_write_perm/pfsw.o
,但实际上打印了 /home/memyself/lkm/procfs_write_perm/src/init.o
。
这看起来有点神奇......
问题: 为什么构建目标 /home/memyself/lkm/procfs_write_perm/pfsw.o
导致构建 /home/memyself/lkm/procfs_write_perm/src/init.o
?代码中哪里指定的?
我知道 real-obj-m
变量包含准确的值,但是 grep
在代码库中我没有找到它取决于某些东西...
正如@Tsyvarev 在评论中暗示的那样,有一条规则可以从 -objs
.
构建 obj-m
在分析行为时,我错误地认为构建 obj-m
的隐式模式规则在我的例子中被扩展为 /home/memyself/lkm/procfs_write_perm/pfsw.o
。 运行 使用 make -p
的构建可以在输出中注意到以下条目:
/home/memyself/lkm/procfs_write_perm/pfsw.o: FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# Implicit rule search has not been done.
# Implicit/static pattern stem: ''
# File is an intermediate prerequisite.
# Last modified 2019-12-18 21:13:48.337755924
# File has been updated.
# Successfully updated.
# automatic
# @ := /home/memyself/lkm/procfs_write_perm/pfsw.o
# automatic
# % :=
# automatic
# * :=
# automatic
# + := FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# automatic
# | :=
# automatic
# < := FORCE
# automatic
# ^ := FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# automatic
# ? := FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=13/382=3%
# recipe to execute (from 'scripts/Makefile.build', line 474):
$(call if_changed,link_multi-m)
@{ echo $(@:.o=.ko); echo $(filter %.o,$^); \
$(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
因此有一个非隐式规则指定要构建的配方 /home/memyself/lkm/procfs_write_perm/pfsw.o
暗示对于该特定情况不应考虑隐式规则 $(obj)/%.o:
。
上面指定的 make
数据库条目还包含要执行的配方的行号和它来自的文件。在这种情况下是
recipe to execute (from 'scripts/Makefile.build', line 474):
指向 scripts/Makefile.build
条目,在我的例子中是
$(multi-used-m): FORCE
$(call if_changed,link_multi-m) # <------ This is the line the database points to
@{ echo $(@:.o=.ko); echo $(filter %.o,$^); \
$(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
$(call multi_depend, $(multi-used-m), .o, -objs -y -m)
我需要一些与构建外部模块相关的KBuild
实现细节建议。
Linux Kernel 5.0.0-32
这是我的 LKM
Makefile:
obj-m += pfsw.o
pfsw-objs := src/init.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
查看 scripts/Makefile.build
and printing the debug output with -d
option I found that the target of this makefile being executed is __build
的实现:
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
@:
因为我正在构建外部 LKM,所以唯一的先决条件是 $(obj-m)
和 $(modorder-target)
。我从数据库中获取了它们的值:
obj-m := /home/memyself/lkm/procfs_write_perm/pfsw.o
modorder-target := /home/memyself/lkm/procfs_write_perm/modules.order
所以要执行 __build
必须首先构建先决条件 /home/memyself/lkm/procfs_write_perm/pfsw.o
。在 Makefile.build
中定义了以下 $(obj)/%.o:
模式规则:
$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
我添加了调试输出来打印目标自动变量的名称:
$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE
@echo "$@"
$(call cmd,force_checksrc)
$(call cmd,force_check_kmsg)
$(call if_changed_rule,cc_o_c)
并期望打印 /home/memyself/lkm/procfs_write_perm/pfsw.o
,但实际上打印了 /home/memyself/lkm/procfs_write_perm/src/init.o
。
这看起来有点神奇......
问题: 为什么构建目标 /home/memyself/lkm/procfs_write_perm/pfsw.o
导致构建 /home/memyself/lkm/procfs_write_perm/src/init.o
?代码中哪里指定的?
我知道 real-obj-m
变量包含准确的值,但是 grep
在代码库中我没有找到它取决于某些东西...
正如@Tsyvarev 在评论中暗示的那样,有一条规则可以从 -objs
.
obj-m
在分析行为时,我错误地认为构建 obj-m
的隐式模式规则在我的例子中被扩展为 /home/memyself/lkm/procfs_write_perm/pfsw.o
。 运行 使用 make -p
的构建可以在输出中注意到以下条目:
/home/memyself/lkm/procfs_write_perm/pfsw.o: FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# Implicit rule search has not been done.
# Implicit/static pattern stem: ''
# File is an intermediate prerequisite.
# Last modified 2019-12-18 21:13:48.337755924
# File has been updated.
# Successfully updated.
# automatic
# @ := /home/memyself/lkm/procfs_write_perm/pfsw.o
# automatic
# % :=
# automatic
# * :=
# automatic
# + := FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# automatic
# | :=
# automatic
# < := FORCE
# automatic
# ^ := FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# automatic
# ? := FORCE /home/memyself/lkm/procfs_write_perm/src/init.o
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=13/382=3%
# recipe to execute (from 'scripts/Makefile.build', line 474):
$(call if_changed,link_multi-m)
@{ echo $(@:.o=.ko); echo $(filter %.o,$^); \
$(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
因此有一个非隐式规则指定要构建的配方 /home/memyself/lkm/procfs_write_perm/pfsw.o
暗示对于该特定情况不应考虑隐式规则 $(obj)/%.o:
。
上面指定的 make
数据库条目还包含要执行的配方的行号和它来自的文件。在这种情况下是
recipe to execute (from 'scripts/Makefile.build', line 474):
指向 scripts/Makefile.build
条目,在我的例子中是
$(multi-used-m): FORCE
$(call if_changed,link_multi-m) # <------ This is the line the database points to
@{ echo $(@:.o=.ko); echo $(filter %.o,$^); \
$(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
$(call multi_depend, $(multi-used-m), .o, -objs -y -m)