Skip to content

Commit d616c2e

Browse files
authored
Optimize cc::Build::try_compile: Reuse PrintThread (#817)
1 parent 1c81432 commit d616c2e

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

src/lib.rs

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,8 +1115,11 @@ impl Build {
11151115

11161116
objects.push(Object::new(file.to_path_buf(), obj));
11171117
}
1118-
self.compile_objects(&objects)?;
1119-
self.assemble(lib_name, &dst.join(gnu_lib_name), &objects)?;
1118+
1119+
let print = PrintThread::new()?;
1120+
1121+
self.compile_objects(&objects, &print)?;
1122+
self.assemble(lib_name, &dst.join(gnu_lib_name), &objects, &print)?;
11201123

11211124
if self.get_target()?.contains("msvc") {
11221125
let compiler = self.get_base_compiler()?;
@@ -1257,7 +1260,7 @@ impl Build {
12571260
}
12581261

12591262
#[cfg(feature = "parallel")]
1260-
fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> {
1263+
fn compile_objects(&self, objs: &[Object], print: &PrintThread) -> Result<(), Error> {
12611264
use std::sync::Once;
12621265

12631266
// Limit our parallelism globally with a jobserver. Start off by
@@ -1286,7 +1289,6 @@ impl Build {
12861289
// With all that in mind we compile all objects in a loop here, after we
12871290
// acquire the appropriate tokens, Once all objects have been compiled
12881291
// we wait on all the processes and propagate the results of compilation.
1289-
let print = PrintThread::new()?;
12901292

12911293
let children = objs
12921294
.iter()
@@ -1369,12 +1371,10 @@ impl Build {
13691371
}
13701372

13711373
#[cfg(not(feature = "parallel"))]
1372-
fn compile_objects(&self, objs: &[Object]) -> Result<(), Error> {
1373-
let print = PrintThread::new()?;
1374-
1374+
fn compile_objects(&self, objs: &[Object], print: &PrintThread) -> Result<(), Error> {
13751375
for obj in objs {
13761376
let (mut cmd, name) = self.create_compile_object_cmd(obj)?;
1377-
run_inner(&mut cmd, &name, print.pipe_writer_cloned()?.unwrap())?;
1377+
run(&mut cmd, &name, print)?;
13781378
}
13791379

13801380
Ok(())
@@ -2087,21 +2087,27 @@ impl Build {
20872087
Ok((cmd, tool.to_string()))
20882088
}
20892089

2090-
fn assemble(&self, lib_name: &str, dst: &Path, objs: &[Object]) -> Result<(), Error> {
2090+
fn assemble(
2091+
&self,
2092+
lib_name: &str,
2093+
dst: &Path,
2094+
objs: &[Object],
2095+
print: &PrintThread,
2096+
) -> Result<(), Error> {
20912097
// Delete the destination if it exists as we want to
20922098
// create on the first iteration instead of appending.
2093-
let _ = fs::remove_file(&dst);
2099+
let _ = fs::remove_file(dst);
20942100

20952101
// Add objects to the archive in limited-length batches. This helps keep
20962102
// the length of the command line within a reasonable length to avoid
20972103
// blowing system limits on limiting platforms like Windows.
20982104
let objs: Vec<_> = objs
20992105
.iter()
2100-
.map(|o| o.dst.clone())
2101-
.chain(self.objects.iter().map(|path| (**path).to_owned()))
2106+
.map(|o| o.dst.as_path())
2107+
.chain(self.objects.iter().map(std::ops::Deref::deref))
21022108
.collect();
21032109
for chunk in objs.chunks(100) {
2104-
self.assemble_progressive(dst, chunk)?;
2110+
self.assemble_progressive(dst, chunk, print)?;
21052111
}
21062112

21072113
if self.cuda && self.cuda_file_count() > 0 {
@@ -2111,12 +2117,9 @@ impl Build {
21112117
let out_dir = self.get_out_dir()?;
21122118
let dlink = out_dir.join(lib_name.to_owned() + "_dlink.o");
21132119
let mut nvcc = self.get_compiler().to_command();
2114-
nvcc.arg("--device-link")
2115-
.arg("-o")
2116-
.arg(dlink.clone())
2117-
.arg(dst);
2118-
run(&mut nvcc, "nvcc")?;
2119-
self.assemble_progressive(dst, &[dlink])?;
2120+
nvcc.arg("--device-link").arg("-o").arg(&dlink).arg(dst);
2121+
run(&mut nvcc, "nvcc", print)?;
2122+
self.assemble_progressive(dst, &[dlink.as_path()], print)?;
21202123
}
21212124

21222125
let target = self.get_target()?;
@@ -2148,13 +2151,18 @@ impl Build {
21482151
// NOTE: We add `s` even if flags were passed using $ARFLAGS/ar_flag, because `s`
21492152
// here represents a _mode_, not an arbitrary flag. Further discussion of this choice
21502153
// can be seen in https://github.com/rust-lang/cc-rs/pull/763.
2151-
run(ar.arg("s").arg(dst), &cmd)?;
2154+
run(ar.arg("s").arg(dst), &cmd, print)?;
21522155
}
21532156

21542157
Ok(())
21552158
}
21562159

2157-
fn assemble_progressive(&self, dst: &Path, objs: &[PathBuf]) -> Result<(), Error> {
2160+
fn assemble_progressive(
2161+
&self,
2162+
dst: &Path,
2163+
objs: &[&Path],
2164+
print: &PrintThread,
2165+
) -> Result<(), Error> {
21582166
let target = self.get_target()?;
21592167

21602168
if target.contains("msvc") {
@@ -2175,7 +2183,7 @@ impl Build {
21752183
cmd.arg(dst);
21762184
}
21772185
cmd.args(objs);
2178-
run(&mut cmd, &program)?;
2186+
run(&mut cmd, &program, print)?;
21792187
} else {
21802188
let (mut ar, cmd, _any_flags) = self.get_ar()?;
21812189

@@ -2206,7 +2214,7 @@ impl Build {
22062214
// NOTE: We add cq here regardless of whether $ARFLAGS/ar_flag have been used because
22072215
// it dictates the _mode_ ar runs in, which the setter of $ARFLAGS/ar_flag can't
22082216
// dictate. See https://github.com/rust-lang/cc-rs/pull/763 for further discussion.
2209-
run(ar.arg("cq").arg(dst).args(objs), &cmd)?;
2217+
run(ar.arg("cq").arg(dst).args(objs), &cmd, print)?;
22102218
}
22112219

22122220
Ok(())
@@ -3507,9 +3515,8 @@ fn run_inner(cmd: &mut Command, program: &str, pipe_writer: File) -> Result<(),
35073515
wait_on_child(cmd, program, &mut child)
35083516
}
35093517

3510-
fn run(cmd: &mut Command, program: &str) -> Result<(), Error> {
3511-
let mut print = PrintThread::new()?;
3512-
run_inner(cmd, program, print.pipe_writer().take().unwrap())?;
3518+
fn run(cmd: &mut Command, program: &str, print: &PrintThread) -> Result<(), Error> {
3519+
run_inner(cmd, program, print.pipe_writer_cloned()?.unwrap())?;
35133520

35143521
Ok(())
35153522
}

0 commit comments

Comments
 (0)