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

Commit fb18729

Browse files
geofftalex
andcommitted
Remove kernel-cflags-finder (fixes #191)
The bulk of this is the changes from #185 that didn't make it into #188. We also upgrade Travis's Clang/LLVM version to 9 to pick up some sort of bugfix in relocation processing. With older versions, we get [ 1827.072410] module: x86/modules: Skipping invalid relocation target, existing value is nonzero for type 1, loc 00000000197e607d, val ffffffffc0703520 (where that "loc" seems to be random/garbage data, disconcertingly). Clang 9 is already required by kernels 5.0+ so this shouldn't be too much of a problem. Co-authored-by: Alex Gaynor <[email protected]>
1 parent dd5dd89 commit fb18729

File tree

10 files changed

+67
-108
lines changed

10 files changed

+67
-108
lines changed

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
matrix:
22
include:
3-
- dist: xenial
43
- dist: bionic
54

65
language: rust
@@ -13,10 +12,11 @@ branches:
1312

1413
install:
1514
- sudo apt-get install -y "linux-headers-$(uname -r)" coreutils
15+
- sudo apt-get install clang-9
1616
- rustup component add rust-src rustfmt clippy
1717

1818
script:
19-
- ./tests/run_tests.py
19+
- CLANG=clang-9 ./tests/run_tests.py
2020
- |
2121
for p in . hello-world tests/*; do
2222
if [ -d "$p" ]; then

README.md

+11-11
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ various other examples in the tests/ directory.
1919
We run [bindgen](https://github.com/rust-lang/rust-bindgen) on the
2020
kernel headers to generate automatic Rust FFI bindings. bindgen is
2121
powered by [Clang](https://clang.llvm.org), so we use the kernel's
22-
own build system to determine the appropriate CFLAGS (see
23-
`kernel-cflags-finder`) and pass them to bindgen (see `build.rs`). Then we
24-
write safe bindings to these types (see the various files inside `src/`).
22+
own build system to determine the appropriate CFLAGS. Then we write safe
23+
bindings to these types (see the various files inside `src/`).
2524

2625
Each kernel module in Rust lives in a `staticlib` crate, which generates
2726
a `.a` file. We pass this object to the Linux kernel's own module build
@@ -50,14 +49,15 @@ for expected status. They'll need src/c_types.rs ported, too.
5049
You'll need to have [Rust](https://www.rust-lang.org) - in particular
5150
Rust nightly, as we use [some unstable
5251
features](https://github.com/fishinabarrel/linux-kernel-module-rust/issues/41) -
53-
and [Clang](https://clang.llvm.org) installed. You need LLVM/Clang 3.9
54-
or higher [to bind constants
55-
properly](https://github.com/rust-lang/rust-bindgen/issues/1316). If
56-
you're running kernel 5.0 or newer, [you'll need Clang
57-
9](https://github.com/fishinabarrel/linux-kernel-module-rust/issues/123)
58-
(released September 2019), which adds support for `asm goto`.
59-
You may need to set the `CLANG` environment variable appropriately,
60-
e.g., `CLANG=clang-9`.
52+
and [Clang](https://clang.llvm.org) installed. You need LLVM/Clang 9
53+
(released September 2019) or higher for multiple reasons, primarily
54+
[support for `asm goto`]
55+
(https://github.com/fishinabarrel/linux-kernel-module-rust/issues/123).
56+
If you're on Debian, Ubuntu, or a derivative, https://apt.llvm.org is
57+
great.
58+
59+
If the binary named `clang` is too old, make sure to set the `CC` or
60+
`CLANG` environment variable appropriately, e.g., `CC=clang-9`.
6161

6262
Very recent kernels may require newer versions of Clang - try Clang 11
6363
if older versions don't work for you.

build.rs

+34-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::io::{BufRead, BufReader};
22
use std::path::PathBuf;
3-
use std::process::Command;
43
use std::{env, fs};
54

65
const INCLUDED_TYPES: &[&str] = &["file_system_type", "mode_t", "umode_t", "ctl_table"];
@@ -112,38 +111,39 @@ fn handle_kernel_symbols_cfg(symvers_path: &PathBuf) {
112111
}
113112
}
114113

115-
fn add_env_if_present(cmd: &mut Command, var: &str) {
116-
if let Ok(val) = env::var(var) {
117-
cmd.env(var, val);
114+
// Takes the CFLAGS from the kernel Makefile and changes all the include paths to be absolute
115+
// instead of relative.
116+
fn prepare_cflags(cflags: &str, kernel_dir: &str) -> Vec<String> {
117+
let cflag_parts = shlex::split(&cflags).unwrap();
118+
let mut cflag_iter = cflag_parts.iter();
119+
let mut kernel_args = vec![];
120+
while let Some(arg) = cflag_iter.next() {
121+
if arg.starts_with("-I") && !arg.starts_with("-I/") {
122+
kernel_args.push(format!("-I{}/{}", kernel_dir, &arg[2..]));
123+
} else if arg == "-include" {
124+
kernel_args.push(arg.to_string());
125+
let include_path = cflag_iter.next().unwrap();
126+
if include_path.starts_with('/') {
127+
kernel_args.push(include_path.to_string());
128+
} else {
129+
kernel_args.push(format!("{}/{}", kernel_dir, include_path));
130+
}
131+
} else {
132+
kernel_args.push(arg.to_string());
133+
}
118134
}
135+
kernel_args
119136
}
120137

121138
fn main() {
122-
println!("cargo:rerun-if-env-changed=KDIR");
123-
let kdir = env::var("KDIR").unwrap_or(format!(
124-
"/lib/modules/{}/build",
125-
std::str::from_utf8(&(Command::new("uname").arg("-r").output().unwrap().stdout))
126-
.unwrap()
127-
.trim()
128-
));
129-
130-
println!("cargo:rerun-if-env-changed=CLANG");
131-
println!("cargo:rerun-if-changed=kernel-cflags-finder/Makefile");
132-
let mut cmd = Command::new("make");
133-
cmd.arg("-C")
134-
.arg("kernel-cflags-finder")
135-
.arg("-s")
136-
.env_clear();
137-
add_env_if_present(&mut cmd, "KDIR");
138-
add_env_if_present(&mut cmd, "CLANG");
139-
add_env_if_present(&mut cmd, "PATH");
140-
let output = cmd.output().unwrap();
141-
if !output.status.success() {
142-
eprintln!("kernel-cflags-finder did not succeed");
143-
eprintln!("stdout: {}", std::str::from_utf8(&output.stdout).unwrap());
144-
eprintln!("stderr: {}", std::str::from_utf8(&output.stderr).unwrap());
145-
std::process::exit(1);
146-
}
139+
println!("cargo:rerun-if-env-changed=CC");
140+
println!("cargo:rerun-if-env-changed=abs_srctree");
141+
println!("cargo:rerun-if-env-changed=c_flags");
142+
143+
let kernel_dir = env::var("abs_srctree").expect("Must be invoked from kernel makefile");
144+
let kernel_cflags = env::var("c_flags").expect("Add 'export c_flags' to Kbuild");
145+
146+
let kernel_args = prepare_cflags(&kernel_cflags, &kernel_dir);
147147

148148
let target = env::var("TARGET").unwrap();
149149

@@ -155,8 +155,8 @@ fn main() {
155155
.rustfmt_bindings(true);
156156

157157
builder = builder.clang_arg(format!("--target={}", target));
158-
for arg in shlex::split(std::str::from_utf8(&output.stdout).unwrap()).unwrap() {
159-
builder = builder.clang_arg(arg.to_string());
158+
for arg in kernel_args.iter() {
159+
builder = builder.clang_arg(arg.clone());
160160
}
161161

162162
println!("cargo:rerun-if-changed=src/bindings_helper.h");
@@ -182,14 +182,14 @@ fn main() {
182182
.expect("Couldn't write bindings!");
183183

184184
handle_kernel_version_cfg(&out_path.join("bindings.rs"));
185-
handle_kernel_symbols_cfg(&PathBuf::from(&kdir).join("Module.symvers"));
185+
handle_kernel_symbols_cfg(&PathBuf::from(&kernel_dir).join("Module.symvers"));
186186

187187
let mut builder = cc::Build::new();
188-
builder.compiler(env::var("CLANG").unwrap_or_else(|_| "clang".to_string()));
188+
builder.compiler(env::var("CC").unwrap_or_else(|_| "clang".to_string()));
189189
builder.target(&target);
190190
builder.warnings(false);
191191
builder.file("src/helpers.c");
192-
for arg in shlex::split(std::str::from_utf8(&output.stdout).unwrap()).unwrap() {
192+
for arg in kernel_args.iter() {
193193
builder.flag(&arg);
194194
}
195195
builder.compile("helpers");

hello-world/Kbuild

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ helloworld-objs := hello_world.rust.o
33

44
CARGO ?= cargo
55

6+
export c_flags
7+
export abs_srctree ?= ${CURDIR}
8+
69
$(src)/target/x86_64-linux-kernel/debug/libhello_world.a: $(src)/Cargo.toml $(wildcard $(src)/src/*.rs)
710
cd $(src); $(CARGO) build -Z build-std=core,alloc --target=x86_64-linux-kernel
811

hello-world/Makefile

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
KDIR ?= /lib/modules/$(shell uname -r)/build
22

3+
CLANG ?= clang
4+
ifeq ($(origin CC),default)
5+
CC := ${CLANG}
6+
endif
7+
38
all:
4-
$(MAKE) -C $(KDIR) M=$(CURDIR)
9+
$(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) CONFIG_CC_IS_CLANG=y
510

611
clean:
7-
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
12+
$(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) clean

kernel-cflags-finder/.gitignore

-12
This file was deleted.

kernel-cflags-finder/Makefile

-35
This file was deleted.

kernel-cflags-finder/README.md

-10
This file was deleted.

tests/Kbuild

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ testmodule-objs := $(TEST_NAME).rust.o
33

44
CARGO ?= cargo
55

6+
export c_flags
7+
export abs_srctree ?= ${CURDIR}
8+
69
$(src)/target/x86_64-linux-kernel/debug/lib%.a: $(src)/$(TEST_PATH)/Cargo.toml $(wildcard $(src)/$(TEST_PATH)/src/*.rs)
710
cd $(src)/$(TEST_PATH); CARGO_TARGET_DIR=../target $(CARGO) build -Z build-std=core,alloc --target=x86_64-linux-kernel
811
cd $(src)/$(TEST_PATH); CARGO_TARGET_DIR=../target $(CARGO) clippy -Z build-std=core,alloc --target=x86_64-linux-kernel -- -Dwarnings

tests/Makefile

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
KDIR ?= /lib/modules/$(shell uname -r)/build
22

3+
CLANG ?= clang
4+
ifeq ($(origin CC),default)
5+
CC := ${CLANG}
6+
endif
7+
38
all:
4-
$(MAKE) -C $(KDIR) M=$(CURDIR)
9+
$(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) CONFIG_CC_IS_CLANG=y
510

611
clean:
7-
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
12+
$(MAKE) -C $(KDIR) M=$(CURDIR) CC=$(CC) clean

0 commit comments

Comments
 (0)