0

我需要一些KBuild与构建外部模块相关的实施细节建议。

Linux Kernel 5.0.0-32

这是我的LKMMakefile:

obj-m += pfsw.o
pfsw-objs := src/init.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

查看scripts/Makefile.build带有选项的调试输出的实现和打印,-d我发现正在执行的这个makefile的目标是__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必须首先构建。中定义了以下$(obj)/%.o:模式规则Makefile.build

$(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根据某些东西我没有找到它的代码库...

4

1 回答 1

0

正如@Tsyvarev 在评论中暗示的那样,有一条规则可以obj-m从它的-objs.

在分析行为时,我错误地考虑了一个隐式模式规则来构建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)
于 2019-12-19T04:37:12.870 回答