为外部Linux内核模块添加KUnit测试时编译报错求助
外部Linux内核模块KUnit测试编译未定义符号问题解决思路
问题背景
为树外构建的外部Linux内核模块“mymod”添加KUnit测试,目标内核版本6.6.33,采用arm64架构交叉编译。原模块无测试时编译正常,添加测试代码到mymod_test.c并修改Makefile后,编译出现__kunit_do_failed_assertion、kunit_fail_assert_format未定义符号错误,调整Makefile后问题仍未解决。
测试代码(mymod_test.c)
#include <kunit/test.h> /* Define the test cases. */ static void mymod_add_test_basic(struct kunit *test) { KUNIT_EXPECT_EQ(test, 1, 1); //test should be ok } static void mymod_test_failure(struct kunit *test) { KUNIT_FAIL(test, "This test never passes."); } static struct kunit_case mymod_test_cases[] = { KUNIT_CASE(mymod_add_test_basic), KUNIT_CASE(mymod_test_failure), {}}; static struct kunit_suite mymod_test_suite = { .name = "mymod", .test_cases = mymod_test_cases, }; kunit_test_suite(mymod_test_suite); MODULE_LICENSE("GPL");
初始Makefile
obj-m += mymod.o mymod-objs += mymod_test.o PWD := $(CURDIR) # Kernel sources KDIR := $(CURDIR)/../linux all: make ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE) -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) clean
编译错误信息
make[1]: Entering directory '/home/alex/mymod' make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C /home/alex/mymod/../linux M=/home/alex/mymod modules make[2]: Entering directory '/home/alex/linux' CC [M] /home/alex/mymod/mymod_test.o LD [M] /home/alex/mymod/mymod.o MODPOST /home/alex/mymod/Module.symvers ERROR: modpost: "__kunit_do_failed_assertion" [/home/alex/mymod/mymod.ko] undefined! ERROR: modpost: "kunit_fail_assert_format" [/home/alex/mymod/mymod.ko] undefined! make[4]: *** [scripts/Makefile.modpost:145: /home/alex/mymod/Module.symvers] Error 1 make[3]: *** [/home/alex/linux/Makefile:1874: modpost] Error 2 make[2]: *** [Makefile:234: __sub-make] Error 2 make[2]: Leaving directory '/home/alex/linux' make[1]: *** [Makefile:9: all] Error 2 make[1]: Leaving directory '/home/alex/mymod' make: *** [Makefile:15: all] Error 2
调整后的无效Makefile
obj-m += mymod.o mymod_test.o # 其余内容与初始Makefile一致
解决思路
- 确认内核KUnit配置开启:目标arm64内核的
.config必须开启CONFIG_KUNIT=y或CONFIG_KUNIT=m,可选开启CONFIG_KUNIT_DEBUGFS=y。进入内核源码目录执行make ARCH=arm64 menuconfig,在Kernel hacking->KUnit - Enable support for unit tests下勾选对应选项,重新编译内核及模块。 - 显式链接KUnit库:在Makefile中添加KUnit编译及链接参数:
或在编译命令中追加ccflags-y += -DKUNIT LDLIBS += -lkunitCONFIG_KUNIT=1:all: make ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE) CONFIG_KUNIT=1 -C $(KDIR) M=$(PWD) modules - 检查符号导出情况:确认内核源码
lib/kunit/assert.c中__kunit_do_failed_assertion、kunit_fail_assert_format是否带有EXPORT_SYMBOL_GPL标记,若内核未开启KUnit,这些符号不会被导出。 - 独立编译测试模块:将测试代码编译为独立模块,修改Makefile为:
obj-m += mymod.o mymod_test.o PWD := $(CURDIR) KDIR := $(CURDIR)/../linux all: make ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE) CONFIG_KUNIT=1 -C $(KDIR) M=$(PWD) modules clean: make -C $(KDIR) M=$(PWD) clean - 验证内核版本匹配:执行
cd $(KDIR) && make kernelversion,确认内核源码版本为6.6.33,避免版本不一致导致符号缺失。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

