使用Autotools构建Linux内核模块需要特殊的配置方法,因为内核模块的构建方式与常规用户空间程序不同。
project/
├── configure.ac
├── Makefile.am
├── src/
│ ├── Makefile.am
│ └── module.c
AC_INIT([my_module], [1.0])
AM_INIT_AUTOMAKE([foreign])
# 检查内核源码路径
AC_ARG_WITH([kernel],
[AS_HELP_STRING([--with-kernel=DIR],
[specify the kernel source directory])],
[KERNEL_DIR=$withval],
[KERNEL_DIR=/lib/modules/`uname -r`/build])
AC_SUBST(KERNEL_DIR)
# 检查内核版本
AC_MSG_CHECKING([for kernel version])
KERNEL_VERSION=`uname -r`
AC_MSG_RESULT([$KERNEL_VERSION])
AC_SUBST(KERNEL_VERSION)
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
SUBDIRS = src
# 指定模块名称
moduledir = /lib/modules/$(KERNEL_VERSION)/extra
# 模块目标文件
module_PROGRAMS = my_module.ko
# 构建规则
my_module.ko: my_module.c
$(MAKE) -C $(KERNEL_DIR) M=$(abs_builddir) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(abs_builddir) clean
# 安装规则
install-data-hook:
depmod -a
# 在configure.ac中添加
AC_ARG_WITH([kernels],
[AS_HELP_STRING([--with-kernels=LIST],
[build for these kernel versions (comma-separated)])],
[KERNELS=`echo $withval | sed 's/,/ /g'`],
[KERNELS=`uname -r`])
AC_SUBST(KERNELS)
# 在configure.ac中添加检查
AC_CHECK_HEADER([linux/module.h], [],
[AC_MSG_ERROR([Linux kernel headers not found])])
# 检查特定内核功能
AC_CHECK_DECL([CONFIG_X86],
[AC_DEFINE([HAVE_X86], [1], [Building for x86 architecture])],
[], [#include <linux/autoconf.h>])
# 在Makefile.am中添加
EXTRA_DIST = module.symvers
BUILT_SOURCES = module.symvers
module.symvers:
touch $@
如果遇到头文件找不到的问题,可以尝试:
./configure --with-kernel=/path/to/kernel/source
构建和安装内核模块通常需要root权限:
sudo make install
对于需要签名的模块:
# 在Makefile.am中添加
if SIGN_MODULES
my_module.ko: my_module.c
$(MAKE) -C $(KERNEL_DIR) M=$(abs_builddir) modules
$(KERNEL_DIR)/scripts/sign-file sha512 /path/to/private.key /path/to/public.der $@
endif
添加调试信息构建:
EXTRA_CFLAGS = -DDEBUG -g
通过以上配置和技巧,您可以有效地使用Autotools来管理和构建Linux内核模块,实现更专业的构建流程和更好的可移植性。