Skip to content

Commit 0a11839

Browse files
Replace shell scripts with integration test
1 parent 36886f1 commit 0a11839

File tree

7 files changed

+284
-331
lines changed

7 files changed

+284
-331
lines changed

.travis.yml

Lines changed: 14 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,26 @@
11
language: rust
22

3-
matrix:
4-
allow_failures:
5-
- rust: nightly
6-
include:
7-
- env: TARGET=x86_64-unknown-linux-gnu
8-
rust: stable
9-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
10-
11-
- env: TARGET=thumbv6m-none-eabi
12-
rust: stable
13-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
14-
15-
- env: TARGET=thumbv7m-none-eabi
16-
rust: stable
17-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
18-
19-
- env: TARGET=thumbv7em-none-eabi
20-
rust: stable
21-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
22-
23-
- env: TARGET=thumbv7em-none-eabihf
24-
rust: stable
25-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
26-
27-
# MSRV
28-
- env: TARGET=thumbv6m-none-eabi
29-
rust: 1.31.0
30-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
31-
32-
# MSRV
33-
- env: TARGET=thumbv7m-none-eabi
34-
rust: 1.31.0
35-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
36-
37-
# MSRV
38-
- env: TARGET=thumbv7em-none-eabi
39-
rust: 1.31.0
40-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
41-
42-
# MSRV
43-
- env: TARGET=thumbv7em-none-eabihf
44-
rust: 1.31.0
45-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
46-
47-
- env: TARGET=thumbv6m-none-eabi
48-
rust: nightly
49-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
50-
51-
- env: TARGET=thumbv7m-none-eabi
52-
rust: nightly
53-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
54-
55-
- env: TARGET=thumbv7em-none-eabi
56-
rust: nightly
57-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
3+
branches:
4+
only:
5+
- master
6+
- staging
7+
- trying
588

59-
- env: TARGET=thumbv7em-none-eabihf
60-
rust: nightly
61-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
9+
rust:
10+
- 1.35.0
11+
- stable
12+
- nightly
6213

63-
- env: TARGET=thumbv8m.main-none-eabi
64-
rust: nightly
65-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
14+
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
6615

67-
- env: TARGET=thumbv8m.base-none-eabi
68-
rust: nightly
69-
if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
16+
matrix:
17+
allow_failures:
18+
- rust: nightly
7019

7120
before_install: set -e
7221

73-
install:
74-
- bash ci/install.sh
75-
7622
script:
77-
- bash ci/script.sh
23+
- cargo test --all
7824

7925
after_script: set +e
8026

@@ -83,12 +29,6 @@ cache: cargo
8329
before_cache:
8430
- chmod -R a+r $HOME/.cargo;
8531

86-
branches:
87-
only:
88-
- master
89-
- staging
90-
- trying
91-
9232
notifications:
9333
email:
9434
on_success: never

ci/install.sh

Lines changed: 0 additions & 11 deletions
This file was deleted.

ci/script.sh

Lines changed: 0 additions & 45 deletions
This file was deleted.

xtask/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@ authors = ["The Cortex-M Team <[email protected]>"]
55
edition = "2018"
66
publish = false
77

8+
[[test]]
9+
name = "ci"
10+
harness = false
11+
812
[dependencies]
913
ar = "0.8.0"

xtask/src/lib.rs

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
//! `cargo xtask` automation.
2+
//!
3+
//! Please refer to <https://github.com/matklad/cargo-xtask/> for an explanation of the concept.
4+
//!
5+
//! Also see the docs in `asm.rs`.
6+
7+
use process::Stdio;
8+
use std::env::current_dir;
9+
use std::{
10+
collections::BTreeMap,
11+
fs::{self, File},
12+
process::{self, Command},
13+
};
14+
15+
fn toolchain() -> String {
16+
fs::read_to_string("asm-toolchain")
17+
.unwrap()
18+
.trim()
19+
.to_string()
20+
}
21+
22+
fn rustc() -> Command {
23+
let mut cmd = Command::new("rustc");
24+
cmd.arg(format!("+{}", toolchain()));
25+
cmd
26+
}
27+
28+
fn assemble_really(target: &str, cfgs: &[&str], plugin_lto: bool) {
29+
let mut cmd = rustc();
30+
31+
// Set the codegen target.
32+
cmd.arg("--target").arg(target);
33+
// Set all the `--cfg` directives for the target.
34+
cmd.args(cfgs.iter().map(|cfg| format!("--cfg={}", cfg)));
35+
36+
// We want some level of debuginfo to allow unwinding through the functions.
37+
cmd.arg("-g");
38+
// We always optimize the assembly shims. There's not really any reason not to.
39+
cmd.arg("-O");
40+
41+
// rustc will usually add frame pointers by default to aid with debugging, but that is a high
42+
// overhead for the tiny assembly routines.
43+
cmd.arg("-Cforce-frame-pointers=no");
44+
45+
// We don't want any system-specific paths to show up since we ship the result to other users.
46+
// Add `--remap-path-prefix $(pwd)=.`.
47+
let mut dir = current_dir().unwrap().as_os_str().to_os_string();
48+
dir.push("=.");
49+
cmd.arg("--remap-path-prefix").arg(dir);
50+
51+
// We let rustc build a single object file, not a staticlib, since the latter pulls in loads of
52+
// code that will never be used (`compiler_builtins` and `core::fmt`, etc.). We build the static
53+
// archive by hand after compiling.
54+
cmd.arg("--emit=obj");
55+
56+
if plugin_lto {
57+
// Make artifacts compatible with Linker-Plugin LTO (and incompatible with everything else).
58+
cmd.arg("-Clinker-plugin-lto");
59+
}
60+
61+
let file_stub = if plugin_lto {
62+
format!("{}-lto", target)
63+
} else {
64+
target.to_string()
65+
};
66+
67+
let obj_file = format!("bin/{}.o", file_stub);
68+
69+
// Pass output and input file.
70+
cmd.arg("-o").arg(&obj_file);
71+
cmd.arg("asm.rs");
72+
73+
println!("{:?}", cmd);
74+
let status = cmd.status().unwrap();
75+
assert!(status.success());
76+
77+
// Archive `target.o` -> `bin/target.a`.
78+
let mut builder = ar::Builder::new(File::create(format!("bin/{}.a", file_stub)).unwrap());
79+
80+
// Use `append`, not `append_path`, to avoid adding any filesystem metadata (modification times,
81+
// etc.).
82+
let file = fs::read(&obj_file).unwrap();
83+
builder
84+
.append(
85+
&ar::Header::new(obj_file.as_bytes().to_vec(), file.len() as u64),
86+
&*file,
87+
)
88+
.unwrap();
89+
90+
fs::remove_file(&obj_file).unwrap();
91+
}
92+
93+
fn assemble(target: &str, cfgs: &[&str]) {
94+
assemble_really(target, cfgs, false);
95+
assemble_really(target, cfgs, true);
96+
}
97+
98+
// `--target` -> `--cfg` list (mirrors what `build.rs` does).
99+
static TARGETS: &[(&str, &[&str])] = &[
100+
("thumbv6m-none-eabi", &[]),
101+
("thumbv7m-none-eabi", &["armv7m"]),
102+
("thumbv7em-none-eabi", &["armv7m", "armv7em"]),
103+
("thumbv7em-none-eabihf", &["armv7m", "armv7em", "has_fpu"]),
104+
("thumbv8m.base-none-eabi", &["armv8m", "armv8m_base"]),
105+
(
106+
"thumbv8m.main-none-eabi",
107+
&["armv7m", "armv8m", "armv8m_main"],
108+
),
109+
(
110+
"thumbv8m.main-none-eabihf",
111+
&["armv7m", "armv8m", "armv8m_main", "has_fpu"],
112+
),
113+
];
114+
115+
pub fn install_targets(targets: &mut dyn Iterator<Item = &str>, toolchain: Option<&str>) {
116+
let mut rustup = Command::new("rustup");
117+
rustup.arg("target").arg("add").args(targets);
118+
119+
if let Some(toolchain) = toolchain {
120+
rustup.arg("--toolchain").arg(toolchain);
121+
}
122+
123+
let status = rustup.status().unwrap();
124+
assert!(status.success(), "rustup command failed: {:?}", rustup);
125+
}
126+
127+
pub fn assemble_blobs() {
128+
let mut cmd = rustc();
129+
cmd.arg("-V");
130+
cmd.stdout(Stdio::null());
131+
let status = cmd.status().unwrap();
132+
let toolchain = toolchain();
133+
134+
if !status.success() {
135+
println!(
136+
"asm toolchain {} does not seem to be installed. installing it now.",
137+
toolchain
138+
);
139+
140+
let mut rustup = Command::new("rustup");
141+
let status = rustup.arg("install").arg(&toolchain).status().unwrap();
142+
assert!(status.success(), "rustup command failed: {:?}", rustup);
143+
}
144+
145+
install_targets(
146+
&mut TARGETS.iter().map(|(target, _)| *target),
147+
Some(&*toolchain),
148+
);
149+
150+
for (target, cfgs) in TARGETS {
151+
println!("building artifacts for {}", target);
152+
assemble(target, cfgs);
153+
}
154+
}
155+
156+
pub fn check_blobs() {
157+
// Load each `.a` file in `bin` into memory.
158+
let mut files_before = BTreeMap::new();
159+
for entry in fs::read_dir("bin").unwrap() {
160+
let entry = entry.unwrap();
161+
if entry.path().extension().unwrap() == "a" {
162+
files_before.insert(
163+
entry
164+
.path()
165+
.file_name()
166+
.unwrap()
167+
.to_str()
168+
.unwrap()
169+
.to_string(),
170+
fs::read(entry.path()).unwrap(),
171+
);
172+
}
173+
}
174+
175+
assemble_blobs();
176+
177+
let mut files_after = BTreeMap::new();
178+
for entry in fs::read_dir("bin").unwrap() {
179+
let entry = entry.unwrap();
180+
if entry.path().extension().unwrap() == "a" {
181+
files_after.insert(
182+
entry
183+
.path()
184+
.file_name()
185+
.unwrap()
186+
.to_str()
187+
.unwrap()
188+
.to_string(),
189+
fs::read(entry.path()).unwrap(),
190+
);
191+
}
192+
}
193+
194+
// Ensure they contain the same files.
195+
let before = files_before.keys().collect::<Vec<_>>();
196+
let after = files_after.keys().collect::<Vec<_>>();
197+
assert_eq!(before, after);
198+
199+
for ((file, before), (_, after)) in files_before.iter().zip(files_after.iter()) {
200+
if before != after {
201+
panic!("{} differs between rebuilds", file);
202+
}
203+
}
204+
205+
println!("Blobs identical.");
206+
}

0 commit comments

Comments
 (0)