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" ] ;
@@ -112,38 +111,39 @@ fn handle_kernel_symbols_cfg(symvers_path: &PathBuf) {
112
111
}
113
112
}
114
113
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
+ }
118
134
}
135
+ kernel_args
119
136
}
120
137
121
138
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) ;
147
147
148
148
let target = env:: var ( "TARGET" ) . unwrap ( ) ;
149
149
@@ -155,8 +155,8 @@ fn main() {
155
155
. rustfmt_bindings ( true ) ;
156
156
157
157
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 ( ) ) ;
160
160
}
161
161
162
162
println ! ( "cargo:rerun-if-changed=src/bindings_helper.h" ) ;
@@ -182,14 +182,14 @@ fn main() {
182
182
. expect ( "Couldn't write bindings!" ) ;
183
183
184
184
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" ) ) ;
186
186
187
187
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 ( ) ) ) ;
189
189
builder. target ( & target) ;
190
190
builder. warnings ( false ) ;
191
191
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 ( ) {
193
193
builder. flag ( & arg) ;
194
194
}
195
195
builder. compile ( "helpers" ) ;
0 commit comments