Skip to content
This repository was archived by the owner on Mar 7, 2021. It is now read-only.

Commit 4c708c2

Browse files
committed
Fixes #177 -- let the kernel build process drive cargo
1 parent ede0645 commit 4c708c2

File tree

7 files changed

+37
-30
lines changed

7 files changed

+37
-30
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ Module.symvers
99
*.mod.c
1010
*.o
1111
modules.order
12+
dummy.c

README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ environment variable appropriately, e.g., `CLANG=clang-9`.
5757

5858
## Building hello-world
5959

60-
1. Install clang, kernel headers, and the `rust-src` and `rustfmt` components from `rustup`:
60+
1. Install clang, kernel headers, and the `rust-src` and `rustfmt` components
61+
from `rustup`:
6162

6263
```
6364
apt-get install llvm clang linux-headers-"$(uname -r)" # or the equivalent for your OS
@@ -70,19 +71,14 @@ rustup component add --toolchain=nightly rust-src rustfmt
7071
cd hello-world
7172
```
7273

73-
3. Build the static object with cargo build, pointing it at our custom target
74-
75-
```
76-
cargo build -Z build-std=core,alloc --target x86_64-linux-kernel
77-
```
78-
79-
4. Build the kernel module using the Linux kernel build system (kbuild)
74+
3. Build the kernel module using the Linux kernel build system (kbuild), this
75+
will invoke `cargo` to build the Rust code
8076

8177
```
8278
make
8379
```
8480

85-
5. Load and unload the module!
81+
4. Load and unload the module!
8682

8783
```
8884
sudo insmod helloworld.ko

build.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,26 @@ fn handle_kernel_version_cfg(bindings_path: &PathBuf) {
8585
}
8686
}
8787

88+
fn add_env_if_present(cmd: &mut Command, var: &str) {
89+
if let Ok(val) = env::var(var) {
90+
cmd.env(var, val);
91+
}
92+
}
93+
8894
fn main() {
8995
println!("cargo:rerun-if-env-changed=KDIR");
9096
println!("cargo:rerun-if-env-changed=CLANG");
9197
println!("cargo:rerun-if-changed=kernel-cflags-finder/Makefile");
92-
let output = Command::new("make")
98+
let mut cmd = Command::new("make");
99+
cmd
93100
.arg("-C")
94101
.arg("kernel-cflags-finder")
95102
.arg("-s")
96-
.output()
97-
.unwrap();
103+
.env_clear();
104+
add_env_if_present(&mut cmd, "KDIR");
105+
add_env_if_present(&mut cmd, "CLANG");
106+
add_env_if_present(&mut cmd, "PATH");
107+
let output = cmd.output().unwrap();
98108
if !output.status.success() {
99109
eprintln!("kernel-cflags-finder did not succeed");
100110
eprintln!("stdout: {}", std::str::from_utf8(&output.stdout).unwrap());
@@ -108,6 +118,7 @@ fn main() {
108118
.derive_default(true)
109119
.rustfmt_bindings(true);
110120

121+
// TODO: Support building for other kernel targets!
111122
builder = builder.clang_arg("--target=x86_64-linux-kernel");
112123
for arg in shlex::split(std::str::from_utf8(&output.stdout).unwrap()).unwrap() {
113124
builder = builder.clang_arg(arg.to_string());
@@ -138,7 +149,6 @@ fn main() {
138149
handle_kernel_version_cfg(&out_path.join("bindings.rs"));
139150

140151
let mut builder = cc::Build::new();
141-
println!("cargo:rerun-if-env-changed=CLANG");
142152
builder.compiler(env::var("CLANG").unwrap_or("clang".to_string()));
143153
builder.target("x86_64-linux-kernel");
144154
builder.warnings(false);

hello-world/Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
ifneq ($(KERNELRELEASE),)
12
obj-m := helloworld.o
23
helloworld-objs := hello_world.rust.o
3-
KDIR ?= /lib/modules/$(shell uname -r)/build
4+
5+
$(src)/target/x86_64-linux-kernel/debug/libhello_world.a: $(src)/Cargo.toml $(wildcard $(src)/src/*.c)
6+
cd $(src); env -u MAKE -u MAKEFLAGS cargo build -Z build-std=core,alloc --target=x86_64-linux-kernel
47

58
%.rust.o: target/x86_64-linux-kernel/debug/lib%.a
69
$(LD) -r -o $@ --whole-archive $<
710

11+
else
12+
KDIR ?= /lib/modules/$(shell uname -r)/build
13+
814
all:
915
$(MAKE) -C $(KDIR) M=$(CURDIR)
1016

1117
clean:
1218
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
19+
endif

kernel-cflags-finder/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
.tmp_versions/
66
Module.symvers
77
built-in.o
8-
dummy.c
98
dummy.ko
109
dummy.mod.c
1110
dummy.mod.o

tests/Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
ifneq ($(KERNELRELEASE),)
12
obj-m := testmodule.o
23
testmodule-objs := $(TEST_NAME).rust.o
3-
KDIR ?= /lib/modules/$(shell uname -r)/build
4+
5+
$(src)/target/x86_64-linux-kernel/debug/lib%.a: $(src)/$(TEST_PATH)/Cargo.toml $(wildcard $(src)/$(TEST_PATH)/src/*.rs)
6+
cd $(src)/$(TEST_PATH); env -u MAKE -u MAKEFLAGS RUSTFLAGS="-Dwarnings" CARGO_TARGET_DIR=../target cargo build -Z build-std=core,alloc --target=x86_64-linux-kernel
47

58
%.rust.o: target/x86_64-linux-kernel/debug/lib%.a
69
$(LD) -r -o $@ --whole-archive $<
710

11+
else
12+
KDIR ?= /lib/modules/$(shell uname -r)/build
13+
814
all:
915
$(MAKE) -C $(KDIR) M=$(CURDIR)
1016

1117
clean:
1218
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
19+
endif

tests/run_tests.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,11 @@ def main():
2525
continue
2626

2727
print("+ [{}]".format(path))
28-
run(
29-
"cargo", "build", "-Zbuild-std=core,alloc",
30-
"--target", "x86_64-linux-kernel",
31-
cwd=os.path.join(BASE_DIR, path),
32-
environ=dict(
33-
os.environ,
34-
RUSTFLAGS="-Dwarnings",
35-
CARGO_TARGET_DIR=os.path.relpath(
36-
os.path.join(BASE_DIR, "target"),
37-
os.path.join(BASE_DIR, path)
38-
),
39-
XBUILD_SYSROOT_PATH=os.path.join(BASE_DIR, "target-sysroot"),
40-
)
41-
)
4228

4329
run(
4430
"make", "-C", BASE_DIR,
4531
"TEST_NAME={}_tests".format(path.replace("-", "_")),
32+
"TEST_PATH={}".format(path),
4633
)
4734
# TODO: qemu
4835
run(

0 commit comments

Comments
 (0)