Skip to content

Commit c8d9470

Browse files
committed
Add semver test infrastructure
This first step add the infrastructure to test if libc follows semantic versioning. In the build step it creates a test file which imports all functions, constants, etc. that are expected to be public. This file is generated from the files in the (not yet included) semver directory. These files include the function and constants expected to be public per target family, vendor, OS, etc. See the do_semver function in the build file of libc-test for the details.
1 parent a309e91 commit c8d9470

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

libc-test/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,8 @@ harness = true
6565
name = "errqueue"
6666
path = "test/errqueue.rs"
6767
harness = true
68+
69+
[[test]]
70+
name = "semver"
71+
path = "test/semver.rs"
72+
harness = false

libc-test/build.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
extern crate cc;
44
extern crate ctest2 as ctest;
55

6-
use std::env;
6+
use std::fs::File;
7+
use std::io::{BufRead, BufReader, BufWriter, Write};
8+
use std::path::{Path, PathBuf};
9+
use std::{env, io};
710

811
fn do_cc() {
912
let target = env::var("TARGET").unwrap();
@@ -63,9 +66,79 @@ fn ctest_cfg() -> ctest::TestGenerator {
6366
cfg
6467
}
6568

69+
fn do_semver() {
70+
let mut out = PathBuf::from(env::var("OUT_DIR").unwrap());
71+
out.push("semver.rs");
72+
let mut output = BufWriter::new(File::create(&out).unwrap());
73+
74+
let family = env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
75+
let vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
76+
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
77+
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
78+
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
79+
80+
// `libc-test/semver` dir.
81+
let mut semver_root =
82+
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
83+
semver_root.push("semver");
84+
85+
// NOTE: Windows has the same `family` as `os`, no point in including it
86+
// twice.
87+
if family != os {
88+
process_semver_file(&mut output, &mut semver_root, &family);
89+
}
90+
process_semver_file(&mut output, &mut semver_root, &vendor);
91+
process_semver_file(&mut output, &mut semver_root, &os);
92+
let os_arch = format!("{}-{}", os, arch);
93+
process_semver_file(&mut output, &mut semver_root, &os_arch);
94+
if target_env != "" {
95+
let os_env = format!("{}-{}", os, target_env);
96+
process_semver_file(&mut output, &mut semver_root, &os_env);
97+
}
98+
}
99+
100+
fn process_semver_file<W: Write, P: AsRef<Path>>(
101+
output: &mut W,
102+
path: &mut PathBuf,
103+
file: P,
104+
) {
105+
// NOTE: `path` is reused between calls, so always remove the file again.
106+
path.push(file);
107+
path.set_extension("txt");
108+
109+
println!("cargo:rerun-if-changed={}", path.display());
110+
let input_file = match File::open(&*path) {
111+
Ok(file) => file,
112+
Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
113+
path.pop();
114+
return;
115+
}
116+
Err(err) => panic!("unexpected error opening file: {}", err),
117+
};
118+
let input = BufReader::new(input_file);
119+
120+
write!(output, "// Source: {}.\n", path.display()).unwrap();
121+
output.write(b"use libc::{\n").unwrap();
122+
for line in input.lines() {
123+
let line = line.unwrap().into_bytes();
124+
match line.first() {
125+
// Ignore comments and empty lines.
126+
Some(b'#') | None => continue,
127+
_ => {
128+
output.write(b" ").unwrap();
129+
output.write(&line).unwrap();
130+
output.write(b",\n").unwrap();
131+
}
132+
}
133+
}
134+
output.write(b"};\n\n").unwrap();
135+
path.pop();
136+
}
137+
66138
fn main() {
67139
do_cc();
68140
do_ctest();
141+
do_semver();
69142
}
70143

71144
macro_rules! headers {

libc-test/test/semver.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![allow(unused_imports)]
2+
#![allow(deprecated)]
3+
4+
extern crate libc;
5+
6+
// Generated in `build.rs`.
7+
include!(concat!(env!("OUT_DIR"), "/semver.rs"));
8+
9+
fn main() {
10+
// The test is about the imports created in `semver.rs`.
11+
}

0 commit comments

Comments
 (0)