Skip to content

Commit 9683f59

Browse files
committed
Don't blindly assume libz exists
Test with an actual compilation to see if `-lz` actually works. If it fails then we fall back to building from source, otherwise we default to using the system libz. Closes #20
1 parent 9e5e71e commit 9683f59

File tree

5 files changed

+68
-6
lines changed

5 files changed

+68
-6
lines changed

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ matrix:
99
- env: LIBZ_SYS_STATIC=1
1010
os: osx
1111

12+
- rust: stable
13+
script:
14+
- cargo generate-lockfile
15+
- ci/run-docker.sh
16+
1217
- rust: beta
1318
- rust: nightly
1419
before_script:

build.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extern crate cc;
66
use std::env;
77
use std::fs;
88
use std::path::PathBuf;
9+
use std::process::Command;
910

1011
fn main() {
1112
println!("cargo:rerun-if-env-changed=LIBZ_SYS_STATIC");
@@ -42,6 +43,8 @@ fn main() {
4243
return
4344
}
4445

46+
let mut cfg = cc::Build::new();
47+
4548
// Whitelist a bunch of situations where we build unconditionally.
4649
//
4750
// MSVC basically never has it preinstalled, MinGW picks up a bunch of weird
@@ -53,20 +56,27 @@ fn main() {
5356
target != host ||
5457
target.contains("musl")
5558
{
56-
return build_zlib(&target);
59+
return build_zlib(&mut cfg, &target);
5760
}
5861

5962
// If we've gotten this far we're probably a pretty standard platform.
60-
// Almost all platforms here ship libz by default, so just assume it exists.
61-
// This is buggy if zlib1g-dev isn't installed on Linux, we should fix that.
62-
println!("cargo:rustc-link-lib=z");
63+
// Almost all platforms here ship libz by default, but some don't have
64+
// pkg-config files that we would find above.
65+
//
66+
// In any case test if zlib is actually installed and if so we link to it,
67+
// otherwise continue below to build things.
68+
if zlib_installed(&mut cfg) {
69+
println!("cargo:rustc-link-lib=z");
70+
return
71+
}
72+
73+
build_zlib(&mut cfg, &target)
6374
}
6475

65-
fn build_zlib(target: &str) {
76+
fn build_zlib(cfg: &mut cc::Build, target: &str) {
6677
let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
6778
let build = dst.join("build");
6879

69-
let mut cfg = cc::Build::new();
7080
cfg.warnings(false)
7181
.out_dir(&build)
7282
.include("src/zlib");
@@ -129,3 +139,20 @@ fn try_vcpkg() -> bool {
129139
},
130140
}
131141
}
142+
143+
fn zlib_installed(cfg: &mut cc::Build) -> bool {
144+
let compiler = cfg.get_compiler();
145+
let mut cmd = Command::new(compiler.path());
146+
cmd.arg("src/smoke.c")
147+
.arg("-o").arg("/dev/null")
148+
.arg("-lz");
149+
150+
println!("running {:?}", cmd);
151+
if let Ok(status) = cmd.status() {
152+
if status.success() {
153+
return true
154+
}
155+
}
156+
157+
false
158+
}

ci/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM ubuntu:18.04
2+
3+
RUN apt-get update -y && apt-get install -y --no-install-recommends \
4+
gcc \
5+
libc6-dev \
6+
ca-certificates
7+

ci/run-docker.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
set -ex
2+
3+
mkdir -p target
4+
5+
docker build --rm -t libz-sys-ci ci
6+
docker run \
7+
--rm \
8+
--init \
9+
--user $(id -u):$(id -g) \
10+
--volume `rustc --print sysroot`:/usr/local:ro \
11+
--volume `pwd`:/src:ro \
12+
--volume `pwd`/target:/src/target \
13+
--workdir /src \
14+
--env CARGO_HOME=/cargo \
15+
--volume $HOME/.cargo:/cargo \
16+
-it \
17+
libz-sys-ci \
18+
cargo run --manifest-path systest/Cargo.toml -vv

src/smoke.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <zlib.h>
2+
3+
int main() {
4+
return (int) adler32;
5+
}

0 commit comments

Comments
 (0)