Skip to content

Commit 8ec03b3

Browse files
committed
auto merge of #11155 : SiegeLord/rust/early_deps, r=pcwalton
The `--dep-info` command line option allows a nice way to generate make-style dependencies, but it currently does so alongside building of the output binary. This isn't a problem for make, as it mixes dependency graph generation and actual building, but it is problematic for other tools (e.g. CMake) which keep them separate. To play more nicely with those tools, I've moved the --dep-info output from phase 6 (linking) up to after phase 2 (expansion of macros). Also, since there was no prior option to do so, I added a command line switch (`--no-analysis`) to stop compilation just before phase 3 (type-checking) which speeds this up even further. Here's the beginning of a CMake function which is enabled by this change: ~~~cmake function(get_rust_deps root_file out_var) execute_process(COMMAND rustc ${RUSTC_FLAGS} --no-analysis --dep-info "${CMAKE_BINARY_DIR}/.deps" "${root_file}") # Read and parse the dependency information file(READ "${CMAKE_BINARY_DIR}/.deps" crate_deps) file(REMOVE "${CMAKE_BINARY_DIR}/.deps") # parsing follows... ~~~
2 parents 5ff7b28 + cbe8c61 commit 8ec03b3

File tree

3 files changed

+62
-31
lines changed

3 files changed

+62
-31
lines changed

src/librustc/driver/driver.rs

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -392,14 +392,56 @@ pub fn phase_5_run_llvm_passes(sess: Session,
392392
/// This should produce either a finished executable or library.
393393
pub fn phase_6_link_output(sess: Session,
394394
trans: &CrateTranslation,
395-
input: &input,
396395
outputs: &OutputFilenames) {
397-
let outputs = time(sess.time_passes(), "linking", (), |_|
396+
time(sess.time_passes(), "linking", (), |_|
398397
link::link_binary(sess,
399398
trans,
400399
&outputs.obj_filename,
401400
&outputs.out_filename,
402401
&trans.link));
402+
}
403+
404+
pub fn stop_after_phase_3(sess: Session) -> bool {
405+
if sess.opts.no_trans {
406+
debug!("invoked with --no-trans, returning early from compile_input");
407+
return true;
408+
}
409+
return false;
410+
}
411+
412+
pub fn stop_after_phase_1(sess: Session) -> bool {
413+
if sess.opts.parse_only {
414+
debug!("invoked with --parse-only, returning early from compile_input");
415+
return true;
416+
}
417+
return false;
418+
}
419+
420+
pub fn stop_after_phase_2(sess: Session) -> bool {
421+
if sess.opts.no_analysis {
422+
debug!("invoked with --no-analysis, returning early from compile_input");
423+
return true;
424+
}
425+
return false;
426+
}
427+
428+
pub fn stop_after_phase_5(sess: Session) -> bool {
429+
if sess.opts.output_type != link::output_type_exe {
430+
debug!("not building executable, returning early from compile_input");
431+
return true;
432+
}
433+
return false;
434+
}
435+
436+
fn write_out_deps(sess: Session, input: &input, outputs: &OutputFilenames, crate: &ast::Crate)
437+
{
438+
let lm = link::build_link_meta(sess, crate.attrs, &outputs.obj_filename,
439+
&mut ::util::sha2::Sha256::new());
440+
441+
let sess_outputs = sess.outputs.borrow();
442+
let out_filenames = sess_outputs.get().iter()
443+
.map(|&output| link::filename_for_input(&sess, output, &lm, &outputs.out_filename))
444+
.to_owned_vec();
403445

404446
// Write out dependency rules to the dep-info file if requested with --dep-info
405447
let deps_filename = match sess.opts.write_dependency_info {
@@ -409,7 +451,7 @@ pub fn phase_6_link_output(sess: Session,
409451
(true, None) => match *input {
410452
file_input(ref input_path) => {
411453
let filestem = input_path.filestem().expect("input file must have stem");
412-
let filename = outputs[0].dir_path().join(filestem).with_extension("d");
454+
let filename = out_filenames[0].dir_path().join(filestem).with_extension("d");
413455
filename
414456
},
415457
str_input(..) => {
@@ -419,40 +461,17 @@ pub fn phase_6_link_output(sess: Session,
419461
},
420462
_ => return,
421463
};
464+
422465
// Build a list of files used to compile the output and
423466
// write Makefile-compatible dependency rules
424467
let files: ~[@str] = sess.codemap.files.iter()
425468
.filter_map(|fmap| if fmap.is_real_file() { Some(fmap.name) } else { None })
426469
.collect();
427470
let mut file = io::File::create(&deps_filename);
428-
for output in outputs.iter() {
471+
for path in out_filenames.iter() {
429472
write!(&mut file as &mut Writer,
430-
"{}: {}\n\n", output.display(), files.connect(" "));
431-
}
432-
}
433-
434-
pub fn stop_after_phase_3(sess: Session) -> bool {
435-
if sess.opts.no_trans {
436-
debug!("invoked with --no-trans, returning early from compile_input");
437-
return true;
438-
}
439-
return false;
440-
}
441-
442-
pub fn stop_after_phase_1(sess: Session) -> bool {
443-
if sess.opts.parse_only {
444-
debug!("invoked with --parse-only, returning early from compile_input");
445-
return true;
473+
"{}: {}\n\n", path.display(), files.connect(" "));
446474
}
447-
return false;
448-
}
449-
450-
pub fn stop_after_phase_5(sess: Session) -> bool {
451-
if sess.opts.output_type != link::output_type_exe {
452-
debug!("not building executable, returning early from compile_input");
453-
return true;
454-
}
455-
return false;
456475
}
457476

458477
pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
@@ -468,6 +487,11 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
468487
};
469488
let outputs = build_output_filenames(input, outdir, output,
470489
expanded_crate.attrs, sess);
490+
491+
write_out_deps(sess, input, outputs, &expanded_crate);
492+
493+
if stop_after_phase_2(sess) { return; }
494+
471495
let analysis = phase_3_run_analysis_passes(sess, &expanded_crate);
472496
if stop_after_phase_3(sess) { return; }
473497
let trans = phase_4_translate_to_llvm(sess, expanded_crate,
@@ -476,7 +500,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
476500
};
477501
phase_5_run_llvm_passes(sess, &trans, outputs);
478502
if stop_after_phase_5(sess) { return; }
479-
phase_6_link_output(sess, &trans, input, outputs);
503+
phase_6_link_output(sess, &trans, outputs);
480504
}
481505

482506
struct IdentifiedAnnotation {
@@ -683,6 +707,7 @@ pub fn build_session_options(binary: @str,
683707

684708
let parse_only = matches.opt_present("parse-only");
685709
let no_trans = matches.opt_present("no-trans");
710+
let no_analysis = matches.opt_present("no-analysis");
686711

687712
let lint_levels = [lint::allow, lint::warn,
688713
lint::deny, lint::forbid];
@@ -836,6 +861,7 @@ pub fn build_session_options(binary: @str,
836861
test: test,
837862
parse_only: parse_only,
838863
no_trans: no_trans,
864+
no_analysis: no_analysis,
839865
debugging_opts: debugging_opts,
840866
android_cross_path: android_cross_path,
841867
write_dependency_info: write_dependency_info,
@@ -929,6 +955,9 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
929955
optflag("", "ls", "List the symbols defined by a library crate"),
930956
optflag("", "no-trans",
931957
"Run all passes except translation; no output"),
958+
optflag("", "no-analysis",
959+
"Parse and expand the output, but run no analysis or produce \
960+
output"),
932961
optflag("O", "", "Equivalent to --opt-level=2"),
933962
optopt("o", "", "Write output to <filename>", "FILENAME"),
934963
optopt("", "opt-level",

src/librustc/driver/session.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ pub struct options {
167167
test: bool,
168168
parse_only: bool,
169169
no_trans: bool,
170+
no_analysis: bool,
170171
debugging_opts: uint,
171172
android_cross_path: Option<~str>,
172173
/// Whether to write dependency files. It's (enabled, optional filename).
@@ -398,6 +399,7 @@ pub fn basic_options() -> @options {
398399
test: false,
399400
parse_only: false,
400401
no_trans: false,
402+
no_analysis: false,
401403
debugging_opts: 0u,
402404
android_cross_path: None,
403405
write_dependency_info: (false, None),

src/librustpkg/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ pub fn compile_crate_from_input(input: &Path,
405405
// -c
406406
if driver::stop_after_phase_5(sess)
407407
|| stop_before == Link || stop_before == Assemble { return Some(outputs.out_filename); }
408-
driver::phase_6_link_output(sess, &translation, &file_input, outputs);
408+
driver::phase_6_link_output(sess, &translation, outputs);
409409

410410
// Register dependency on the source file
411411
// FIXME (#9639): This needs to handle non-utf8 paths

0 commit comments

Comments
 (0)