1
1
use std:: io:: { BufRead , BufReader } ;
2
2
use std:: path:: PathBuf ;
3
- use std:: process:: Command ;
4
3
use std:: { env, fs} ;
5
4
6
5
const INCLUDED_TYPES : & [ & str ] = & [ "file_system_type" , "mode_t" , "umode_t" , "ctl_table" ] ;
@@ -100,38 +99,39 @@ fn handle_kernel_symbols_cfg(symvers_path: &PathBuf) {
100
99
}
101
100
}
102
101
103
- fn add_env_if_present ( cmd : & mut Command , var : & str ) {
104
- if let Ok ( val) = env:: var ( var) {
105
- cmd. env ( var, val) ;
102
+ // Takes the CFLAGS from the kernel Makefile and changes all the include paths to be absolute
103
+ // instead of relative.
104
+ fn prepare_cflags ( cflags : & str , kernel_dir : & str ) -> Vec < String > {
105
+ let cflag_parts = shlex:: split ( & cflags) . unwrap ( ) ;
106
+ let mut cflag_iter = cflag_parts. iter ( ) ;
107
+ let mut kernel_args = vec ! [ ] ;
108
+ while let Some ( arg) = cflag_iter. next ( ) {
109
+ if arg. starts_with ( "-I" ) && !arg. starts_with ( "-I/" ) {
110
+ kernel_args. push ( format ! ( "-I{}/{}" , kernel_dir, & arg[ 2 ..] ) ) ;
111
+ } else if arg == "-include" {
112
+ kernel_args. push ( arg. to_string ( ) ) ;
113
+ let include_path = cflag_iter. next ( ) . unwrap ( ) ;
114
+ if include_path. starts_with ( "/" ) {
115
+ kernel_args. push ( include_path. to_string ( ) ) ;
116
+ } else {
117
+ kernel_args. push ( format ! ( "{}/{}" , kernel_dir, include_path) ) ;
118
+ }
119
+ } else {
120
+ kernel_args. push ( arg. to_string ( ) ) ;
121
+ }
106
122
}
123
+ kernel_args
107
124
}
108
125
109
126
fn main ( ) {
110
- println ! ( "cargo:rerun-if-env-changed=KDIR" ) ;
111
- let kdir = env:: var ( "KDIR" ) . unwrap_or ( format ! (
112
- "/lib/modules/{}/build" ,
113
- std:: str :: from_utf8( & ( Command :: new( "uname" ) . arg( "-r" ) . output( ) . unwrap( ) . stdout) )
114
- . unwrap( )
115
- . trim( )
116
- ) ) ;
117
-
118
- println ! ( "cargo:rerun-if-env-changed=CLANG" ) ;
119
- println ! ( "cargo:rerun-if-changed=kernel-cflags-finder/Makefile" ) ;
120
- let mut cmd = Command :: new ( "make" ) ;
121
- cmd. arg ( "-C" )
122
- . arg ( "kernel-cflags-finder" )
123
- . arg ( "-s" )
124
- . env_clear ( ) ;
125
- add_env_if_present ( & mut cmd, "KDIR" ) ;
126
- add_env_if_present ( & mut cmd, "CLANG" ) ;
127
- add_env_if_present ( & mut cmd, "PATH" ) ;
128
- let output = cmd. output ( ) . unwrap ( ) ;
129
- if !output. status . success ( ) {
130
- eprintln ! ( "kernel-cflags-finder did not succeed" ) ;
131
- eprintln ! ( "stdout: {}" , std:: str :: from_utf8( & output. stdout) . unwrap( ) ) ;
132
- eprintln ! ( "stderr: {}" , std:: str :: from_utf8( & output. stderr) . unwrap( ) ) ;
133
- std:: process:: exit ( 1 ) ;
134
- }
127
+ println ! ( "cargo:rerun-if-env-changed=CC" ) ;
128
+ println ! ( "cargo:rerun-if-env-changed=abs_srctree" ) ;
129
+ println ! ( "cargo:rerun-if-env-changed=c_flags" ) ;
130
+
131
+ let kernel_dir = env:: var ( "abs_srctree" ) . expect ( "Must be invoked from kernel makefile" ) ;
132
+ let kernel_cflags = env:: var ( "c_flags" ) . expect ( "Add 'export c_flags' to Kbuild" ) ;
133
+
134
+ let kernel_args = prepare_cflags ( & kernel_cflags, & kernel_dir) ;
135
135
136
136
let target = env:: var ( "TARGET" ) . unwrap ( ) ;
137
137
@@ -143,8 +143,8 @@ fn main() {
143
143
. rustfmt_bindings ( true ) ;
144
144
145
145
builder = builder. clang_arg ( format ! ( "--target={}" , target) ) ;
146
- for arg in shlex :: split ( std :: str :: from_utf8 ( & output . stdout ) . unwrap ( ) ) . unwrap ( ) {
147
- builder = builder. clang_arg ( arg. to_string ( ) ) ;
146
+ for arg in kernel_args . iter ( ) {
147
+ builder = builder. clang_arg ( arg. clone ( ) ) ;
148
148
}
149
149
150
150
println ! ( "cargo:rerun-if-changed=src/bindings_helper.h" ) ;
@@ -170,14 +170,14 @@ fn main() {
170
170
. expect ( "Couldn't write bindings!" ) ;
171
171
172
172
handle_kernel_version_cfg ( & out_path. join ( "bindings.rs" ) ) ;
173
- handle_kernel_symbols_cfg ( & PathBuf :: from ( & kdir ) . join ( "Module.symvers" ) ) ;
173
+ handle_kernel_symbols_cfg ( & PathBuf :: from ( & kernel_dir ) . join ( "Module.symvers" ) ) ;
174
174
175
175
let mut builder = cc:: Build :: new ( ) ;
176
- builder. compiler ( env:: var ( "CLANG " ) . unwrap_or_else ( |_| "clang" . to_string ( ) ) ) ;
176
+ builder. compiler ( env:: var ( "CC " ) . unwrap_or_else ( |_| "clang" . to_string ( ) ) ) ;
177
177
builder. target ( & target) ;
178
178
builder. warnings ( false ) ;
179
179
builder. file ( "src/helpers.c" ) ;
180
- for arg in shlex :: split ( std :: str :: from_utf8 ( & output . stdout ) . unwrap ( ) ) . unwrap ( ) {
180
+ for arg in kernel_args . iter ( ) {
181
181
builder. flag ( & arg) ;
182
182
}
183
183
builder. compile ( "helpers" ) ;
0 commit comments