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.
This commit is contained in:
Thomas de Zeeuw 2021-03-13 14:13:10 +01:00
parent a309e9124b
commit c8d9470502
3 changed files with 90 additions and 1 deletions

View File

@ -65,3 +65,8 @@ harness = true
name = "errqueue"
path = "test/errqueue.rs"
harness = true
[[test]]
name = "semver"
path = "test/semver.rs"
harness = false

View File

@ -3,7 +3,10 @@
extern crate cc;
extern crate ctest2 as ctest;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::{Path, PathBuf};
use std::{env, io};
fn do_cc() {
let target = env::var("TARGET").unwrap();
@ -63,9 +66,79 @@ fn ctest_cfg() -> ctest::TestGenerator {
cfg
}
fn do_semver() {
let mut out = PathBuf::from(env::var("OUT_DIR").unwrap());
out.push("semver.rs");
let mut output = BufWriter::new(File::create(&out).unwrap());
let family = env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
let vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap();
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
// `libc-test/semver` dir.
let mut semver_root =
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
semver_root.push("semver");
// NOTE: Windows has the same `family` as `os`, no point in including it
// twice.
if family != os {
process_semver_file(&mut output, &mut semver_root, &family);
}
process_semver_file(&mut output, &mut semver_root, &vendor);
process_semver_file(&mut output, &mut semver_root, &os);
let os_arch = format!("{}-{}", os, arch);
process_semver_file(&mut output, &mut semver_root, &os_arch);
if target_env != "" {
let os_env = format!("{}-{}", os, target_env);
process_semver_file(&mut output, &mut semver_root, &os_env);
}
}
fn process_semver_file<W: Write, P: AsRef<Path>>(
output: &mut W,
path: &mut PathBuf,
file: P,
) {
// NOTE: `path` is reused between calls, so always remove the file again.
path.push(file);
path.set_extension("txt");
println!("cargo:rerun-if-changed={}", path.display());
let input_file = match File::open(&*path) {
Ok(file) => file,
Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
path.pop();
return;
}
Err(err) => panic!("unexpected error opening file: {}", err),
};
let input = BufReader::new(input_file);
write!(output, "// Source: {}.\n", path.display()).unwrap();
output.write(b"use libc::{\n").unwrap();
for line in input.lines() {
let line = line.unwrap().into_bytes();
match line.first() {
// Ignore comments and empty lines.
Some(b'#') | None => continue,
_ => {
output.write(b" ").unwrap();
output.write(&line).unwrap();
output.write(b",\n").unwrap();
}
}
}
output.write(b"};\n\n").unwrap();
path.pop();
}
fn main() {
do_cc();
do_ctest();
do_semver();
}
macro_rules! headers {

11
libc-test/test/semver.rs Normal file
View File

@ -0,0 +1,11 @@
#![allow(unused_imports)]
#![allow(deprecated)]
extern crate libc;
// Generated in `build.rs`.
include!(concat!(env!("OUT_DIR"), "/semver.rs"));
fn main() {
// The test is about the imports created in `semver.rs`.
}