编译Rust版Linux内核模块遇target.json不存在错误求助
编译Rust Linux内核模块时出现
target file "./scripts/target.json" does not exist错误 错误信息
error: target file "./scripts/target.json" does not exist make[3]: *** [scripts/Makefile.build:292: /home/guilherme/repositories/rust_learn/hello_world_lkm/hello_world.o] Error 1 make[2]: *** [/home/guilherme/repositories/linux/Makefile:1913: /home/guilherme/repositories/rust_learn/hello_world_lkm] Error 2 make[1]: *** [Makefile:234: __sub-make] Error 2 make[1]: Saindo do diretório '/home/guilherme/repositories/linux'
环境配置
- Rust版本:
$ rustc --version rustc 1.73.0 (cc66ad468 2023-10-03)
- Cargo版本:
$ cargo --version cargo 1.73.0 (9c4383fb5 2023-08-26)
- Clang版本:
$ clang --version clang version 16.0.6 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin
- 内核Rust支持状态:
$ make LLVM=1 rustavailable Rust is available!
已在内核配置中启用Rust支持。
Rust模块代码
use kernel::prelude::* module! { type: HelloWorld, name: b"HelloWorld", license b"GPL" }; struct HelloWorld; impl kernel::Module for HelloWorld { fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> { pr_info!("Hello world"); Ok(HelloWorld) } } impl Drop for HelloWorld { fn drop(&mut self) { pr_info!("Adeus mundo cruel fdp"); } }
Makefile内容
PWD := $(shell pwd) obj-m += hello_world.o CLANG ?= clang ifeq ($(origin CC),default) CC := ${CLANG} endif all: $(MAKE) -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) CC=$(CC) CONFIG_CC_IS_CLANG=y modules clean: $(MAKE) -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
解决方案
1. 修正Makefile的内核路径
你当前Makefile使用系统默认内核头文件路径,但错误显示编译时调用了本地内核源码目录/home/guilherme/repositories/linux。需将Makefile的-C参数改为你已配置Rust支持的本地内核源码路径,同时添加LLVM=1参数(内核Rust编译必须依赖LLVM工具链):
all: $(MAKE) -C /home/guilherme/repositories/linux/ M=$(PWD) LLVM=1 CONFIG_CC_IS_CLANG=y modules
2. 生成内核Rust编译所需的target.json
进入本地内核源码目录,执行以下命令生成Rust编译依赖的目标配置文件:
make LLVM=1 defconfig make LLVM=1 prepare
3. 修复Rust代码的语法错误
代码存在3处语法问题,修正后如下:
use kernel::prelude::*; use kernel::{CStr, ThisModule}; module! { type: HelloWorld, name: b"HelloWorld", license: b"GPL", }; struct HelloWorld; impl kernel::Module for HelloWorld { fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> { pr_info!("Hello world\n"); Ok(HelloWorld) } } impl Drop for HelloWorld { fn drop(&mut self) { pr_info!("Adeus mundo cruel fdp\n"); } }
- 补充
use语句末尾的分号 module!宏中license字段添加冒号与逗号- 显式导入
CStr和ThisModule类型 - 日志输出添加换行符,符合内核日志规范
4. 确认Rust版本与内核兼容
内核对Rust版本有严格要求,可查看内核源码目录下Documentation/rust/quick-start.rst文件确认所需版本。若当前rustc 1.73.0不兼容,使用rustup切换版本:
rustup toolchain install <内核要求版本> rustup default <该版本>
内容的提问来源于stack exchange,提问作者Guilherme Giácomo Simoes
相关产品推荐
相关产品推荐

