Skip to content

Commit 4a5c3bf

Browse files
committed
Re-implement the build of zlib
1 parent ed8b221 commit 4a5c3bf

File tree

1 file changed

+101
-37
lines changed

1 file changed

+101
-37
lines changed

build.rs

Lines changed: 101 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::fs::read_dir;
77
use std::path;
88
use std::path::Path;
99
use std::process;
10+
use std::process::ExitStatus;
1011

1112
use 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-
406434
fn 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

Comments
 (0)