@@ -7,6 +7,7 @@ use std::fs::read_dir;
77use std:: path;
88use std:: path:: Path ;
99use std:: process;
10+ use std:: process:: ExitStatus ;
1011
1112use nix:: fcntl;
1213
@@ -151,10 +152,10 @@ fn main() {
151152 pkg_check ( "flex" ) ;
152153 pkg_check ( "bison" ) ;
153154 pkg_check ( "gawk" ) ;
155+ pkg_check ( "aclocal" ) ;
154156 }
155157
156158 let ( compiler, mut cflags) = if vendored_libbpf || vendored_libelf || vendored_zlib {
157- pkg_check ( "make" ) ;
158159 pkg_check ( "pkg-config" ) ;
159160
160161 let compiler = cc:: Build :: new ( ) . try_get_compiler ( ) . expect (
@@ -213,45 +214,73 @@ fn main() {
213214 }
214215}
215216
216- fn make_zlib ( compiler : & cc:: Tool , src_dir : & path:: Path , out_dir : & path:: Path ) {
217- let src_dir = src_dir. join ( "zlib" ) ;
217+ fn make_zlib ( compiler : & cc:: Tool , src_dir : & path:: Path , _: & path:: Path ) {
218218 // lock README such that if two crates are trying to compile
219219 // this at the same time (eg libbpf-rs libbpf-cargo)
220220 // they wont trample each other
221- let file = std:: fs:: File :: open ( src_dir. join ( "README" ) ) . unwrap ( ) ;
222- let _lock = fcntl:: Flock :: lock ( file, fcntl:: FlockArg :: LockExclusive ) . unwrap ( ) ;
223-
224- let status = process:: Command :: new ( "./configure" )
225- . arg ( "--static" )
226- . arg ( "--prefix" )
227- . arg ( "." )
228- . arg ( "--libdir" )
229- . arg ( out_dir)
230- . env ( "CC" , compiler. path ( ) )
231- . env ( "CFLAGS" , compiler. cflags_env ( ) )
232- . current_dir ( & src_dir)
233- . status ( )
234- . expect ( "could not execute make" ) ;
235-
236- assert ! ( status. success( ) , "make failed" ) ;
221+ let project_dir = src_dir. join ( "zlib" ) ;
237222
238- let status = process:: Command :: new ( "make" )
239- . arg ( "install" )
240- . arg ( "-j" )
241- . arg ( & format ! ( "{}" , num_cpus( ) ) )
242- . current_dir ( & src_dir)
243- . status ( )
244- . expect ( "could not execute make" ) ;
223+ let file = std:: fs:: File :: open ( project_dir. join ( "README" ) ) . unwrap ( ) ;
224+ let _lock = fcntl:: Flock :: lock ( file, fcntl:: FlockArg :: LockExclusive ) . unwrap ( ) ;
245225
246- assert ! ( status. success( ) , "make failed" ) ;
226+ let project_dir = project_dir. to_str ( ) . unwrap ( ) ;
227+
228+ let zlib_sources = [
229+ "adler32.c" ,
230+ "compress.c" ,
231+ "crc32.c" ,
232+ "deflate.c" ,
233+ "gzclose.c" ,
234+ "gzlib.c" ,
235+ "gzread.c" ,
236+ "gzwrite.c" ,
237+ "infback.c" ,
238+ "inffast.c" ,
239+ "inflate.c" ,
240+ "inftrees.c" ,
241+ "trees.c" ,
242+ "uncompr.c" ,
243+ "zutil.c" ,
244+ ] ;
245+
246+ // These flags are only used in Android
247+ // ref: https://android.googlesource.com/platform/external/zlib/+/refs/tags/android-11.0.0_r48/Android.bp
248+ let android_cflags = [
249+ // We do support hidden visibility, so turn that on.
250+ "-DHAVE_HIDDEN" ,
251+ // We do support const, so turn that on.
252+ "-DZLIB_CONST" ,
253+ // Enable -O3 as per chromium.
254+ "-O3" ,
255+ // "-Wall",
256+ // "-Werror",
257+ // "-Wno-deprecated-non-prototype",
258+ // "-Wno-unused",
259+ // "-Wno-unused-parameter",
260+ ] ;
261+
262+ configure ( project_dir, vec ! [ ] ) ;
263+
264+ let mut builder = cc:: Build :: new ( ) ;
265+
266+ builder. include ( project_dir) . files ( {
267+ zlib_sources
268+ . iter ( )
269+ . map ( |source| format ! ( "{project_dir}/{source}" ) )
270+ } ) ;
271+
272+ if build_android ( ) {
273+ for flag in android_cflags {
274+ builder. flag ( flag) ;
275+ }
276+ } else {
277+ for flag in compiler. args ( ) {
278+ builder. flag ( flag) ;
279+ }
280+ }
247281
248- let status = process:: Command :: new ( "make" )
249- . arg ( "distclean" )
250- . current_dir ( & src_dir)
251- . status ( )
252- . expect ( "could not execute make" ) ;
282+ builder. flag_if_supported ( "-w" ) . warnings ( false ) . compile ( "z" ) ;
253283
254- assert ! ( status. success( ) , "make failed" ) ;
255284 emit_rerun_directives_for_contents ( & src_dir) ;
256285}
257286
@@ -402,9 +431,44 @@ fn num_cpus() -> usize {
402431 std:: thread:: available_parallelism ( ) . map_or ( 1 , |count| count. get ( ) )
403432}
404433
405-
406434fn build_android ( ) -> bool {
407435 env:: var ( "CARGO_CFG_TARGET_OS" )
408- . expect ( "CARGO_CFG_TARGET_OS not set" )
409- . eq ( "android" )
410- }
436+ . expect ( "CARGO_CFG_TARGET_OS not set" )
437+ . eq ( "android" )
438+ }
439+
440+ fn configure < ' a , P , A > ( project_dir : P , args : A )
441+ where
442+ P : AsRef < str > ,
443+ A : IntoIterator < Item = & ' a str > ,
444+ {
445+ let project_dir = project_dir. as_ref ( ) ;
446+
447+ let prog = format ! ( "{project_dir}/configure" ) ;
448+
449+ unsafe {
450+ let prog = std:: ffi:: CString :: new ( prog. as_bytes ( ) ) . unwrap ( ) ;
451+ nix:: libc:: chmod ( prog. as_ptr ( ) , 0o755 ) ;
452+ }
453+
454+ let status = subproc ( prog, project_dir, args) ;
455+
456+ assert ! (
457+ status. success( ) ,
458+ "configure({}) failed: {}" ,
459+ project_dir,
460+ status
461+ ) ;
462+ }
463+
464+ fn subproc < ' a , P , A > ( prog : P , workdir : & str , args : A ) -> ExitStatus
465+ where
466+ P : AsRef < str > ,
467+ A : IntoIterator < Item = & ' a str > ,
468+ {
469+ process:: Command :: new ( prog. as_ref ( ) )
470+ . current_dir ( workdir)
471+ . args ( args)
472+ . status ( )
473+ . expect ( & format ! ( "could not execute `{}`" , prog. as_ref( ) ) )
474+ }
0 commit comments