11use std:: io:: { BufRead , BufReader } ;
22use std:: path:: PathBuf ;
3- use std:: process:: Command ;
43use std:: { env, fs} ;
54
65const 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
121138fn 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" ) ;
0 commit comments